[Ocfs2-tools-commits] zab commits r337 - in trunk: fsck.ocfs2
fsck.ocfs2/include libocfs2 libocfs2/include
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Tue Oct 19 19:44:23 CDT 2004
Author: zab
Date: 2004-10-19 19:44:21 -0500 (Tue, 19 Oct 2004)
New Revision: 337
Added:
trunk/fsck.ocfs2/include/journal.h
trunk/fsck.ocfs2/journal.c
Modified:
trunk/fsck.ocfs2/Makefile
trunk/fsck.ocfs2/fsck.c
trunk/fsck.ocfs2/include/pass1.h
trunk/fsck.ocfs2/pass1.c
trunk/fsck.ocfs2/pass2.c
trunk/libocfs2/include/jfs_compat.h
trunk/libocfs2/include/ocfs2.h
trunk/libocfs2/mkjournal.c
trunk/libocfs2/ocfs2_err.et.in
Log:
o journal replay in fsck that seems to do something. still fragile.
Modified: trunk/fsck.ocfs2/Makefile
===================================================================
--- trunk/fsck.ocfs2/Makefile 2004-10-19 18:21:39 UTC (rev 336)
+++ trunk/fsck.ocfs2/Makefile 2004-10-20 00:44:21 UTC (rev 337)
@@ -17,6 +17,7 @@
dirblocks.c \
dirparents.c \
icount.c \
+ journal.c \
pass1.c \
pass2.c \
pass3.c \
@@ -29,6 +30,7 @@
include/dirblocks.h \
include/dirparents.h \
include/icount.h \
+ include/journal.h \
include/pass1.h \
include/pass2.h \
include/pass3.h \
Modified: trunk/fsck.ocfs2/fsck.c
===================================================================
--- trunk/fsck.ocfs2/fsck.c 2004-10-19 18:21:39 UTC (rev 336)
+++ trunk/fsck.ocfs2/fsck.c 2004-10-20 00:44:21 UTC (rev 337)
@@ -34,6 +34,7 @@
#include "fsck.h"
#include "icount.h"
+#include "journal.h"
#include "pass1.h"
#include "pass2.h"
#include "pass3.h"
@@ -254,10 +255,9 @@
/* XXX do we want checking for different revisions of ocfs2? */
- /* XXX worry about the journal */
+ /* XXX should be verifying super-block bits here.
+ * like s_max_nodes, journal recovery trusts it. */
- /* XXX should be verifying super-block bits here. */
-
/* ocfs2_open() already checked _incompat and _ro_compat */
if (OCFS2_RAW_SB(ost->ost_fs->fs_super)->s_feature_compat &
~OCFS2_FEATURE_COMPAT_SUPP) {
@@ -276,6 +276,8 @@
printf(" number of clusters: %"PRIu32"\n", ost->ost_fs->fs_clusters);
printf(" bytes per cluster: %u\n", ost->ost_fs->fs_clustersize);
+ o2fsck_replay_journals(ost);
+
ret = o2fsck_pass1(ost);
if (ret)
com_err(argv[0], ret, "pass1 failed");
Added: trunk/fsck.ocfs2/include/journal.h
===================================================================
--- trunk/fsck.ocfs2/include/journal.h 2004-10-19 18:21:39 UTC (rev 336)
+++ trunk/fsck.ocfs2/include/journal.h 2004-10-20 00:44:21 UTC (rev 337)
@@ -0,0 +1,32 @@
+/*
+ * journal.h
+ *
+ * Copyright (C) 2002 Oracle Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Author: Zach Brown
+ */
+
+#ifndef __O2FSCK_JOURNAL_H__
+#define __O2FSCK_JOURNAL_H__
+
+#include "fsck.h"
+
+errcode_t o2fsck_replay_journals(o2fsck_state *ost);
+
+#endif /* __O2FSCK_JOURNAL_H__ */
+
Modified: trunk/fsck.ocfs2/include/pass1.h
===================================================================
--- trunk/fsck.ocfs2/include/pass1.h 2004-10-19 18:21:39 UTC (rev 336)
+++ trunk/fsck.ocfs2/include/pass1.h 2004-10-20 00:44:21 UTC (rev 337)
@@ -27,6 +27,7 @@
#include "fsck.h"
errcode_t o2fsck_pass1(o2fsck_state *ost);
+void o2fsck_mark_block_used(o2fsck_state *ost, uint64_t blkno);
#endif /* __O2FSCK_PASS1_H__ */
Added: trunk/fsck.ocfs2/journal.c
===================================================================
--- trunk/fsck.ocfs2/journal.c 2004-10-19 18:21:39 UTC (rev 336)
+++ trunk/fsck.ocfs2/journal.c 2004-10-20 00:44:21 UTC (rev 337)
@@ -0,0 +1,525 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * journal.c
+ *
+ * file system checker for OCFS2
+ *
+ * Copyright (C) 2004 Oracle. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License, version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Authors: Zach Brown
+ */
+#include <stdint.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "fsck.h"
+#include "journal.h"
+/* jfs_compat.h defines these */
+#undef cpu_to_be32
+#undef be32_to_cpu
+#include "jfs_user.h"
+#include "ocfs2.h"
+#include "pass1.h"
+#include "util.h"
+
+static char *whoami = "journal recovery";
+
+struct journal_info {
+ int ji_node;
+ uint64_t ji_ino;
+ struct rb_root ji_revoke;
+ journal_superblock_t *ji_jsb;
+ uint64_t ji_jsb_block;
+ ocfs2_cached_inode *ji_cinode;
+
+ uint32_t ji_final_seq;
+};
+
+struct revoke_entry {
+ struct rb_node r_node;
+ uint64_t r_block;
+ uint32_t r_seq;
+};
+
+static int seq_gt(uint32_t x, uint32_t y)
+{
+ int32_t diff = x - y;
+ return diff > 0;
+}
+static int seq_geq(uint32_t x, uint32_t y)
+{
+ int32_t diff = x - y;
+ return diff >= 0;
+}
+
+static void revoke_insert(struct rb_root *root, uint64_t block, uint32_t seq)
+{
+ struct rb_node ** p = &root->rb_node;
+ struct rb_node * parent = NULL;
+ struct revoke_entry *re;
+
+ while (*p)
+ {
+ parent = *p;
+ re = rb_entry(parent, struct revoke_entry, r_node);
+
+ if (block < re->r_block)
+ p = &(*p)->rb_left;
+ else if (block > re->r_block)
+ p = &(*p)->rb_right;
+ else {
+ if (seq_gt(seq, re->r_seq))
+ re->r_seq = seq;
+ return;
+ }
+ }
+
+ re = malloc(sizeof(struct revoke_entry));
+ if (re == NULL)
+ fatal_error(OCFS2_ET_NO_MEMORY, "while allocating "
+ "space for revoke entries");
+
+ re->r_block = block;
+ re->r_seq = seq;
+
+ rb_link_node(&re->r_node, parent, p);
+ rb_insert_color(&re->r_node, root);
+}
+
+static int revoke_this_block(struct rb_root *root, uint64_t block,
+ uint32_t seq)
+{
+ struct rb_node *node = root->rb_node;
+ struct revoke_entry *re;
+
+ while (node) {
+ re = rb_entry(node, struct revoke_entry, r_node);
+
+ if (block < re->r_block)
+ node = node->rb_left;
+ else if (block > re->r_block)
+ node = node->rb_right;
+ else {
+ /* only revoke if we've recorded a revoke entry for
+ * this block that is <= the seq that we're interested
+ * in */
+ if (re && !seq_gt(seq, re->r_seq)) {
+ verbosef("%"PRIu64" is revoked\n", block);
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void revoke_free_all(struct rb_root *root)
+{
+ struct revoke_entry *re;
+ struct rb_node *node;
+
+ while((node = rb_first(root)) != NULL) {
+ re = rb_entry(node, struct revoke_entry, r_node);
+ rb_erase(node, root);
+ free(re);
+ }
+}
+
+static void add_revoke_records(struct journal_info *ji, char *buf,
+ size_t max, uint32_t seq)
+{
+ journal_revoke_header_t jr;
+ uint32_t *blkno; /* XXX 640k ought to be enough for everybody */
+ size_t i, num;
+
+ memcpy(&jr, buf, sizeof(jr));
+ jr.r_count = be32_to_cpu(jr.r_count);
+
+ if (jr.r_count < sizeof(jr) || jr.r_count > max) {
+ /* XXX abort replay? */
+ verbosef("corrupt r_count: %X", jr.r_count);
+ return;
+ }
+
+ num = (jr.r_count - sizeof(jr)) / sizeof(blkno);
+ blkno = (uint32_t *)(buf + sizeof(jr));
+
+ for (i = 0; i < num; i++, blkno++)
+ revoke_insert(&ji->ji_revoke, be32_to_cpu(*blkno), seq);
+}
+
+static uint64_t jwrap(journal_superblock_t *jsb, uint64_t block)
+{
+ uint64_t diff = jsb->s_maxlen - jsb->s_first;
+
+ if (diff == 0) /* ugh */
+ return 0;
+
+ while (block > jsb->s_maxlen)
+ block -= diff;
+
+ return block;
+}
+
+static uint64_t count_tags(char *buf, size_t size)
+{
+ journal_block_tag_t *tag, *last;
+ uint64_t nr = 0;
+
+ if (size < sizeof(journal_header_t) + sizeof(*tag))
+ return 0;
+
+ tag = (journal_block_tag_t *)&buf[sizeof(journal_header_t)];
+ last = (journal_block_tag_t *)&buf[size - sizeof(*tag)];
+
+ for(; tag <= last; tag++) {
+ nr++;
+ if (tag->t_flags & cpu_to_be32(JFS_FLAG_LAST_TAG))
+ break;
+ /* inline uuids are 16 bytes, tags are 8 */
+ if (!(tag->t_flags & cpu_to_be32(JFS_FLAG_SAME_UUID)))
+ tag += 2;
+ }
+
+ return nr;
+}
+
+static errcode_t lookup_journal_block(o2fsck_state *ost,
+ struct journal_info *ji,
+ uint64_t blkoff,
+ uint64_t *blkno)
+{
+ errcode_t err;
+ int contig;
+
+ err = ocfs2_extent_map_get_blocks(ji->ji_cinode->ci_map, blkoff,
+ 1, blkno, &contig);
+ if (err)
+ com_err(whoami, err, "while looking up logical block "
+ "%"PRIu64" in node %d's journal", blkoff, ji->ji_node);
+#if 0
+ /* XXX when we more aggresively track blocks.. */
+ o2fsck_mark_block_used(ost, *blkno);
+#endif
+
+ return err;
+}
+
+static errcode_t read_journal_block(o2fsck_state *ost,
+ struct journal_info *ji,
+ uint64_t blkoff,
+ char *buf)
+{
+ errcode_t err;
+ uint64_t blkno;
+
+ err = lookup_journal_block(ost, ji, blkoff, &blkno);
+ if (err)
+ return err;
+
+ err = io_read_block(ost->ost_fs->fs_io, blkno, 1, buf);
+ if (err)
+ com_err(whoami, err, "while reading block %"PRIu64" of node "
+ "%d's journal", blkno, ji->ji_node);
+
+ return err;
+}
+
+static errcode_t replay_blocks(o2fsck_state *ost, struct journal_info *ji,
+ char *buf, uint64_t seq, uint64_t *next_block)
+{
+ journal_block_tag_t tag, *tagp;
+ size_t i, num;
+ char *io_buf = NULL;
+ errcode_t err, ret = 0;
+
+ tagp = (journal_block_tag_t *)(buf + sizeof(journal_header_t));
+ num = (ji->ji_jsb->s_blocksize - sizeof(journal_header_t)) /
+ sizeof(tag);
+
+ ret = ocfs2_malloc_blocks(ost->ost_fs->fs_io, 1, &io_buf);
+ if (ret) {
+ com_err(whoami, ret, "while allocating a block buffer");
+ goto out;
+ }
+
+ for(i = 0; i < num; i++, tagp++, (*next_block)++) {
+ memcpy(&tag, tagp, sizeof(tag));
+ tag.t_flags = be32_to_cpu(tag.t_flags);
+ tag.t_blocknr = be32_to_cpu(tag.t_blocknr);
+
+ *next_block = jwrap(ji->ji_jsb, *next_block);
+
+ verbosef("recovering journal block %"PRIu64" to disk block "
+ "%"PRIu32"\n", *next_block, tag.t_blocknr);
+
+ if (revoke_this_block(&ji->ji_revoke, tag.t_blocknr, seq))
+ goto skip_io;
+
+ err = read_journal_block(ost, ji, *next_block, io_buf);
+ if (err) {
+ ret = err;
+ goto skip_io;
+ }
+
+ if (tag.t_flags & JFS_FLAG_ESCAPE) {
+ uint32_t magic = cpu_to_be32(JFS_MAGIC_NUMBER);
+ memcpy(io_buf, &magic, sizeof(magic));
+ }
+
+ err = io_write_block(ost->ost_fs->fs_io, tag.t_blocknr, 1,
+ io_buf);
+ if (err)
+ ret = err;
+
+ skip_io:
+ if (tag.t_flags & JFS_FLAG_LAST_TAG)
+ i = num; /* be sure to increment next_block */
+ /* inline uuids are 16 bytes, tags are 8 */
+ if (!(tag.t_flags & JFS_FLAG_SAME_UUID))
+ tagp += 2;
+ }
+
+out:
+ if (io_buf)
+ ocfs2_free(&io_buf);
+ return ret;
+}
+
+static errcode_t walk_journal(o2fsck_state *ost, int node,
+ struct journal_info *ji, char *buf, int recover)
+{
+ errcode_t err = 0;
+ uint32_t next_seq;
+ uint64_t next_block;
+ journal_superblock_t *jsb = ji->ji_jsb;
+ journal_header_t jh;
+
+ next_seq = jsb->s_sequence;
+ next_block = jsb->s_start;
+
+ /* s_start == 0 when we have nothing to do */
+ if (next_block == 0)
+ return 0;
+
+ while(1) {
+ verbosef("next_seq %"PRIu32" next_block %"PRIu64"\n", next_seq,
+ next_block);
+
+ if (recover && seq_geq(next_seq, ji->ji_final_seq))
+ break;
+
+ err = read_journal_block(ost, ji, next_block, buf);
+ if (err)
+ break;
+
+ next_block = jwrap(jsb, next_block + 1);
+
+ memcpy(&jh, buf, sizeof(jh));
+ jh.h_magic = be32_to_cpu(jh.h_magic);
+ jh.h_blocktype = be32_to_cpu(jh.h_blocktype);
+ jh.h_sequence = be32_to_cpu(jh.h_sequence);
+
+ verbosef("jh magic %x\n", jh.h_magic);
+
+ if (jh.h_magic != JFS_MAGIC_NUMBER)
+ break;
+
+ verbosef("jh block %x\n", jh.h_blocktype);
+ verbosef("jh seq %"PRIu32"\n", jh.h_sequence);
+
+ if (jh.h_sequence != next_seq)
+ break;
+
+ switch(jh.h_blocktype) {
+ case JFS_DESCRIPTOR_BLOCK:
+ verbosef("found a desc type %x\n", jh.h_blocktype);
+ if (!recover) {
+ next_block = jwrap(jsb, next_block +
+ count_tags(buf, jsb->s_blocksize));
+ continue;
+ }
+
+ err = replay_blocks(ost, ji, buf, next_seq,
+ &next_block);
+ break;
+
+ case JFS_COMMIT_BLOCK:
+ verbosef("found a commit type %x\n", jh.h_blocktype);
+ next_seq++;
+ break;
+
+ case JFS_REVOKE_BLOCK:
+ verbosef("found a revoke type %x\n", jh.h_blocktype);
+ add_revoke_records(ji, buf, jsb->s_blocksize,
+ next_seq);
+ break;
+
+ default:
+ verbosef("unknown type %x\n", jh.h_blocktype);
+ break;
+ }
+ }
+
+ verbosef("done scanning with seq %"PRIu32"\n", next_seq);
+
+ if (!recover)
+ ji->ji_final_seq = next_seq;
+ else if (ji->ji_final_seq != next_seq) {
+ err = OCFS2_ET_IO;
+ com_err(whoami, err, "while recovering the journal and found "
+ "that we arrived at seq %"PRIu32" instead of seq "
+ "%"PRIu32" as we expected from a previous scan.",
+ next_seq, ji->ji_final_seq);
+ }
+
+ return err;
+}
+
+static errcode_t prep_journal_info(o2fsck_state *ost, int node,
+ struct journal_info *ji)
+{
+ errcode_t err;
+
+ ji->ji_revoke = RB_ROOT;
+ ji->ji_node = node;
+
+ err = ocfs2_malloc_blocks(ost->ost_fs->fs_io, 1, &ji->ji_jsb);
+ if (err)
+ fatal_error(err, "while allocating space for node %d's "
+ "journal superblock", node);
+
+ err = ocfs2_lookup_system_inode(ost->ost_fs, JOURNAL_SYSTEM_INODE,
+ node, &ji->ji_ino);
+ if (err) {
+ com_err(whoami, err, "while looking up the journal inode for "
+ "node %d", node);
+ goto out;
+ }
+
+ err = ocfs2_read_cached_inode(ost->ost_fs, ji->ji_ino, &ji->ji_cinode);
+ if (err) {
+ com_err(whoami, err, "while reading cached inode %"PRIu64" "
+ "for node %d's journal", ji->ji_ino, node);
+ goto out;
+ }
+
+ err = ocfs2_extent_map_new(ost->ost_fs, ji->ji_cinode,
+ &ji->ji_cinode->ci_map);
+ if (err) {
+ com_err(whoami, err, "while initializing extent map");
+ goto out;
+ }
+
+ err = lookup_journal_block(ost, ji, 0, &ji->ji_jsb_block);
+ if (err)
+ goto out;
+
+ /* XXX be smarter about reading in the whole super block if it
+ * spans multiple blocks */
+ err = ocfs2_read_journal_superblock(ost->ost_fs, ji->ji_jsb_block,
+ (char *)ji->ji_jsb);
+ if (err) {
+ com_err(whoami, err, "while reading block %"PRIu64" as node "
+ "%d's journal super block", ji->ji_jsb_block,
+ ji->ji_node);
+ goto out;
+ }
+
+ verbosef("jsb start %u maxlen %u\n", ji->ji_jsb->s_start,
+ ji->ji_jsb->s_maxlen);
+out:
+ return err;
+}
+
+/* XXX we should think harder about what behaviour we want here. Right now
+ * this function always leaves with clean reset journals. Any errors in
+ * the journal recovery process will trigger a full fsck.
+ * XXX pass fsck trigger back up, write dirty fs, always zap/write */
+errcode_t o2fsck_replay_journals(o2fsck_state *ost)
+{
+ errcode_t err = 0, ret = 0;
+ struct journal_info *jis, *ji;
+ char *buf = NULL;
+ int i, max_nodes;
+
+ max_nodes = OCFS2_RAW_SB(ost->ost_fs->fs_super)->s_max_nodes;
+
+ err = ocfs2_malloc_blocks(ost->ost_fs->fs_io, 1, &buf);
+ if (err)
+ fatal_error(err, "while allocating room to read journal "
+ "blocks");
+
+ err = ocfs2_malloc0(sizeof(struct journal_info) * max_nodes, &jis);
+ if (err)
+ fatal_error(err, "while allocating an array of block numbers "
+ "for journal replay");
+
+ /* we'll try loading and verifying them all first before proceeding
+ * to replay them. This way we can make sure their blocks don't
+ * overlap or anything crazy like that. */
+ for (i = 0; i < max_nodes ; i++) {
+ err = prep_journal_info(ost, i, &jis[i]);
+ if (err) {
+ ret = err;
+ continue;
+ }
+
+ err = walk_journal(ost, i, &jis[i], buf, 0);
+ if (err) {
+ ret = err;
+ }
+ }
+
+ for (i = 0, ji = jis; ret == 0 && i < max_nodes; i++, ji++) {
+ err = walk_journal(ost, i, ji, buf, 1);
+ if (err) {
+ ret = err;
+ continue;
+ }
+
+ /* only write back the journal super block if we found out
+ * where it was to begin with */
+ if (ji->ji_jsb_block != 0) {
+ journal_superblock_t *jsb = ji->ji_jsb;
+
+ /* reset the journal */
+ jsb->s_start = 0;
+ /* XXX and if we haven't set final_seq? */
+ jsb->s_sequence = ji->ji_final_seq + 1;
+
+ err = ocfs2_write_journal_superblock(ost->ost_fs,
+ ji->ji_jsb_block, ji->ji_jsb);
+ if (err)
+ ret = err;
+ }
+
+ if (jis[i].ji_jsb)
+ ocfs2_free(&jis[i].ji_jsb);
+ if (jis[i].ji_cinode)
+ ocfs2_free_cached_inode(ost->ost_fs, jis[i].ji_cinode);
+ revoke_free_all(&jis[i].ji_revoke);
+ }
+
+ if (jis)
+ ocfs2_free(&jis);
+ if (buf)
+ ocfs2_free(&buf);
+
+ return ret;
+}
Modified: trunk/fsck.ocfs2/pass1.c
===================================================================
--- trunk/fsck.ocfs2/pass1.c 2004-10-19 18:21:39 UTC (rev 336)
+++ trunk/fsck.ocfs2/pass1.c 2004-10-20 00:44:21 UTC (rev 337)
@@ -39,7 +39,7 @@
static const char *whoami = "pass1";
-static void mark_block_used(o2fsck_state *ost, uint64_t blkno)
+void o2fsck_mark_block_used(o2fsck_state *ost, uint64_t blkno)
{
int was_set;
ocfs2_bitmap_set(ost->ost_found_blocks, blkno, &was_set);
@@ -305,7 +305,7 @@
struct verifying_blocks *vb = priv_data;
verbosef("found gd block %"PRIu64"\n", gd_blkno);
/* don't have bcount */
- mark_block_used(vb->vb_ost, gd_blkno);
+ o2fsck_mark_block_used(vb->vb_ost, gd_blkno);
vb_saw_block(vb, vb->vb_num_blocks);
return 0;
}
@@ -319,7 +319,7 @@
if (tree_depth > 0) {
verbosef("found extent block %"PRIu64"\n", rec->e_blkno);
- mark_block_used(vb->vb_ost, rec->e_blkno);
+ o2fsck_mark_block_used(vb->vb_ost, rec->e_blkno);
}
return 0;
@@ -448,6 +448,8 @@
if (!(di->i_flags & OCFS2_VALID_FL))
continue;
+ verbosef("found inode %"PRIu64"\n", blkno);
+
o2fsck_verify_inode_fields(fs, ost, blkno, di);
/* XXX be able to mark the blocks in the inode as
Modified: trunk/fsck.ocfs2/pass2.c
===================================================================
--- trunk/fsck.ocfs2/pass2.c 2004-10-19 18:21:39 UTC (rev 336)
+++ trunk/fsck.ocfs2/pass2.c 2004-10-20 00:44:21 UTC (rev 337)
@@ -461,6 +461,8 @@
dbe->e_blkno);
}
+ verbosef("dir block %"PRIu64"\n", dbe->e_blkno);
+
while (offset < dd->fs->fs_blocksize) {
dirent = (struct ocfs2_dir_entry *)(dd->buf + offset);
Modified: trunk/libocfs2/include/jfs_compat.h
===================================================================
--- trunk/libocfs2/include/jfs_compat.h 2004-10-19 18:21:39 UTC (rev 336)
+++ trunk/libocfs2/include/jfs_compat.h 2004-10-20 00:44:21 UTC (rev 337)
@@ -4,9 +4,7 @@
#include "kernel-list.h"
#include <errno.h>
-#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
-#endif
// libocfs.h has these
//#define printk printf
Modified: trunk/libocfs2/include/ocfs2.h
===================================================================
--- trunk/libocfs2/include/ocfs2.h 2004-10-19 18:21:39 UTC (rev 336)
+++ trunk/libocfs2/include/ocfs2.h 2004-10-20 00:44:21 UTC (rev 337)
@@ -274,6 +274,10 @@
errcode_t ocfs2_create_journal_superblock(ocfs2_filesys *fs,
uint32_t size, int flags,
char **ret_jsb);
+errcode_t ocfs2_read_journal_superblock(ocfs2_filesys *fs, uint64_t blkno,
+ char *jsb_buf);
+errcode_t ocfs2_write_journal_superblock(ocfs2_filesys *fs, uint64_t blkno,
+ char *jsb_buf);
errcode_t ocfs2_read_extent_block(ocfs2_filesys *fs, uint64_t blkno,
char *eb_buf);
Modified: trunk/libocfs2/mkjournal.c
===================================================================
--- trunk/libocfs2/mkjournal.c 2004-10-19 18:21:39 UTC (rev 336)
+++ trunk/libocfs2/mkjournal.c 2004-10-20 00:44:21 UTC (rev 337)
@@ -92,6 +92,99 @@
return 0;
}
+errcode_t ocfs2_read_journal_superblock(ocfs2_filesys *fs, uint64_t blkno,
+ char *jsb_buf)
+{
+ errcode_t ret;
+ char *blk;
+ journal_superblock_t *disk, *jsb;
+
+ if ((blkno < OCFS2_SUPER_BLOCK_BLKNO) ||
+ (blkno > fs->fs_blocks))
+ return OCFS2_ET_BAD_BLKNO;
+
+ ret = ocfs2_malloc_block(fs->fs_io, &blk);
+ if (ret)
+ return ret;
+
+ ret = io_read_block(fs->fs_io, blkno, 1, blk);
+ if (ret)
+ goto out;
+
+ disk = (journal_superblock_t *)blk;
+ jsb = (journal_superblock_t *)jsb_buf;
+
+ if (disk->s_header.h_magic != htonl(JFS_MAGIC_NUMBER)) {
+ ret = OCFS2_ET_BAD_JOURNAL_SUPERBLOCK_MAGIC;
+ goto out;
+ }
+
+ memcpy(jsb_buf, blk, fs->fs_blocksize);
+
+ /* XXX incomplete */
+ jsb->s_header.h_magic = be32_to_cpu(disk->s_header.h_magic);
+ jsb->s_header.h_blocktype = be32_to_cpu(disk->s_header.h_blocktype);
+
+ jsb->s_blocksize = be32_to_cpu(disk->s_blocksize);
+ jsb->s_maxlen = be32_to_cpu(disk->s_maxlen);
+ jsb->s_first = be32_to_cpu(disk->s_first);
+ jsb->s_start = be32_to_cpu(disk->s_start);
+ jsb->s_sequence = be32_to_cpu(disk->s_sequence);
+ jsb->s_errno = be32_to_cpu(disk->s_errno);
+
+ ret = 0;
+out:
+ ocfs2_free(&blk);
+
+ return ret;
+}
+
+errcode_t ocfs2_write_journal_superblock(ocfs2_filesys *fs, uint64_t blkno,
+ char *jsb_buf)
+{
+ errcode_t ret;
+ char *blk;
+ journal_superblock_t *disk, *jsb;
+
+ if (!(fs->fs_flags & OCFS2_FLAG_RW))
+ return OCFS2_ET_RO_FILESYS;
+
+ if ((blkno < OCFS2_SUPER_BLOCK_BLKNO) ||
+ (blkno > fs->fs_blocks))
+ return OCFS2_ET_BAD_BLKNO;
+
+ ret = ocfs2_malloc_block(fs->fs_io, &blk);
+ if (ret)
+ return ret;
+
+ disk = (journal_superblock_t *)blk;
+ jsb = (journal_superblock_t *)jsb_buf;
+
+ memcpy(blk, jsb_buf, fs->fs_blocksize);
+
+ /* XXX incomplete */
+ disk->s_header.h_magic = cpu_to_be32(jsb->s_header.h_magic);
+ disk->s_header.h_blocktype = cpu_to_be32(jsb->s_header.h_blocktype);
+
+ disk->s_blocksize = cpu_to_be32(jsb->s_blocksize);
+ disk->s_maxlen = cpu_to_be32(jsb->s_maxlen);
+ disk->s_first = cpu_to_be32(jsb->s_first);
+ disk->s_start = cpu_to_be32(jsb->s_start);
+ disk->s_sequence = cpu_to_be32(jsb->s_sequence);
+ disk->s_errno = cpu_to_be32(jsb->s_errno);
+
+ ret = io_write_block(fs->fs_io, blkno, 1, blk);
+ if (ret)
+ goto out;
+
+ fs->fs_flags |= OCFS2_FLAG_CHANGED;
+ ret = 0;
+out:
+ ocfs2_free(&blk);
+
+ return ret;
+}
+
#ifdef DEBUG_EXE
#if 0
static uint64_t read_number(const char *num)
Modified: trunk/libocfs2/ocfs2_err.et.in
===================================================================
--- trunk/libocfs2/ocfs2_err.et.in 2004-10-19 18:21:39 UTC (rev 336)
+++ trunk/libocfs2/ocfs2_err.et.in 2004-10-20 00:44:21 UTC (rev 337)
@@ -56,6 +56,9 @@
ec OCFS2_ET_JOURNAL_TOO_SMALL,
"Journal must be at least 1024 blocks"
+ec OCFS2_ET_BAD_JOURNAL_SUPERBLOCK_MAGIC,
+ "Bad magic number in journal superblock"
+
ec OCFS2_ET_INODE_NOT_VALID,
"Inode is not valid (active)"
More information about the Ocfs2-tools-commits
mailing list