[Ocfs2-tools-devel] [PATCH 3/3] Ocfs2-tools: Implement new prompt codes of journal for fswreck.
Tristan Ye
tristan.ye at oracle.com
Wed Jul 1 23:52:39 PDT 2009
We want fswreck to support journal's corruptions as fsck.ocfs2
has had such kind of prompt codes already.
Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
---
fswreck/Makefile | 3 +-
fswreck/corrupt.c | 12 +++
fswreck/include/fsck_type.h | 6 ++
fswreck/include/journal.h | 23 ++++++
fswreck/include/main.h | 1 +
fswreck/journal.c | 174 +++++++++++++++++++++++++++++++++++++++++++
fswreck/main.c | 8 ++
7 files changed, 225 insertions(+), 2 deletions(-)
create mode 100644 fswreck/include/journal.h
create mode 100644 fswreck/journal.c
diff --git a/fswreck/Makefile b/fswreck/Makefile
index 3848cc2..bfd937b 100644
--- a/fswreck/Makefile
+++ b/fswreck/Makefile
@@ -10,12 +10,11 @@ INCLUDES += $(GLIB_CFLAGS)
UNINST_PROGRAMS = fswreck
-CFILES = main.c corrupt.c chain.c extent.c group.c inode.c local_alloc.c truncate_log.c special.c symlink.c dir.c
+CFILES = main.c corrupt.c chain.c extent.c group.c inode.c local_alloc.c truncate_log.c special.c symlink.c dir.c journal.c
HFILES = \
include/main.h \
include/corrupt.h \
- include/chain.c
OBJS = $(subst .c,.o,$(CFILES))
diff --git a/fswreck/corrupt.c b/fswreck/corrupt.c
index a9e5188..484b21e 100644
--- a/fswreck/corrupt.c
+++ b/fswreck/corrupt.c
@@ -323,6 +323,18 @@ void corrupt_sys_file(ocfs2_filesys *fs, enum fsck_type type, uint16_t slotnum)
case INODE_ALLOC_REPAIR:
func = mess_up_inode_alloc;
break;
+ case JOURNAL_FILE_INVALID:
+ func = mess_up_journal;
+ break;
+ case JOURNAL_UNKNOWN_FEATURE:
+ func = mess_up_journal;
+ break;
+ case JOURNAL_MISS_FEATURE:
+ func = mess_up_journal;
+ break;
+ case JOURNAL_TOO_SMALL:
+ func = mess_up_journal;
+ break;
default:
FSWRK_FATAL("Invalid code=%d", type);
}
diff --git a/fswreck/include/fsck_type.h b/fswreck/include/fsck_type.h
index 6f90dae..b506300 100644
--- a/fswreck/include/fsck_type.h
+++ b/fswreck/include/fsck_type.h
@@ -122,6 +122,10 @@ enum fsck_type
INODE_INLINE_SIZE,
INODE_INLINE_CLUSTERS,
DUPLICATE_CLUSTERS,
+ JOURNAL_FILE_INVALID,
+ JOURNAL_UNKNOWN_FEATURE,
+ JOURNAL_MISS_FEATURE,
+ JOURNAL_TOO_SMALL,
NUM_FSCK_TYPE
};
@@ -179,6 +183,8 @@ enum fsck_type
*
* Special files error: ROOT_NOTDIR, ROOT_DIR_MISSING, LOSTFOUND_MISSING,
* DIR_DOTDOT
+ * Journal file error: JOURNAL_FILE_INVALID, JOURNAL_UNKNOWN_FEATURE,
+ JOURNAL_MISS_FEATURE, JOURNAL_TOO_SMALL.
*
* Link file error: LINK_FAST_DATA, LINK_NULLTERM, LINK_SIZE, LINK_BLOCKS
*
diff --git a/fswreck/include/journal.h b/fswreck/include/journal.h
new file mode 100644
index 0000000..93f5238
--- /dev/null
+++ b/fswreck/include/journal.h
@@ -0,0 +1,23 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * journal.h
+ *
+ * Copyright (C) 2004, 2008 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.
+ */
+
+#ifndef __JOURNAL_H
+#define __JOURNAL_H
+
+void mess_up_journal(ocfs2_filesys *fs, enum fsck_type type, uint16_t slotnum);
+
+#endif /* __JOURNAL_H */
diff --git a/fswreck/include/main.h b/fswreck/include/main.h
index 9c3dfe4..daedc0a 100644
--- a/fswreck/include/main.h
+++ b/fswreck/include/main.h
@@ -88,5 +88,6 @@
#include "symlink.h"
#include "special.h"
#include "dir.h"
+#include "journal.h"
#endif /* __MAIN_H__ */
diff --git a/fswreck/journal.c b/fswreck/journal.c
new file mode 100644
index 0000000..47b2e36
--- /dev/null
+++ b/fswreck/journal.c
@@ -0,0 +1,174 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * journal.c
+ *
+ * Copyright (C) 2004, 2008 Oracle. All rights reserved.
+ *
+ * Corruptions for journal system file.
+ *
+ * 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.
+ */
+
+#include "main.h"
+
+extern char *progname;
+
+/* This file will corrupt jorunal system file.
+ *
+ * Journal Error: JOURNAL_FILE_INVALID, JOURNAL_UNKNOWN_FEATURE,
+ * JOURNAL_MISS_FEATURE, JOURNAL_TOO_SMALL.
+ *
+ */
+void mess_up_journal(ocfs2_filesys *fs, enum fsck_type type, uint16_t slotnum)
+{
+ errcode_t ret;
+ uint64_t j_blkno, jsb_blkno;
+ uint64_t contig;
+ uint32_t old_no;
+ uint16_t max_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
+ ocfs2_cached_inode *ci = NULL;
+ char *buf = NULL;
+ journal_superblock_t *jsb;
+
+ uint64_t tmp_j_blkno, tmp_jsb_blkno;
+ uint64_t tmp_contig;
+ uint16_t adj_slotnum;
+ ocfs2_cached_inode *tmp_ci = NULL;
+ journal_superblock_t *tmp_jsb;
+ char *tmp_buf = NULL;
+
+ ret = ocfs2_malloc_block(fs->fs_io, &buf);
+ if (ret)
+ FSWRK_COM_FATAL(progname, ret);
+
+ ret = ocfs2_lookup_system_inode(fs, JOURNAL_SYSTEM_INODE,
+ slotnum, &j_blkno);
+ if (ret)
+ FSWRK_COM_FATAL(progname, ret);
+
+ ret = ocfs2_read_cached_inode(fs, j_blkno, &ci);
+ if (ret)
+ FSWRK_COM_FATAL(progname, ret);
+
+ ret = ocfs2_extent_map_get_blocks(ci, 0, 1, &jsb_blkno, &contig, NULL);
+ if (ret)
+ FSWRK_COM_FATAL(progname, ret);
+
+ ret = ocfs2_read_journal_superblock(fs, jsb_blkno, buf);
+ if (ret)
+ FSWRK_COM_FATAL(progname, ret);
+
+ jsb = (journal_superblock_t *)buf;
+
+ switch (type) {
+ case JOURNAL_FILE_INVALID:
+ old_no = JBD2_MAGIC_NUMBER;
+ jsb->s_header.h_magic = ~JBD2_MAGIC_NUMBER;
+ fprintf(stdout, "JOURNAL_FILE_INVALID: "
+ "Corrupt journal system inode#%"PRIu64"'s "
+ "superblock's magic number from %x to %x.\n",
+ j_blkno, old_no, jsb->s_header.h_magic);
+ break;
+ case JOURNAL_UNKNOWN_FEATURE:
+ jsb->s_feature_incompat |= ~JBD2_KNOWN_INCOMPAT_FEATURES;
+ jsb->s_feature_ro_compat |= ~JBD2_KNOWN_ROCOMPAT_FEATURES;
+ fprintf(stdout, "JOURNAL_FILE_INVALID: "
+ "Corrupt journal system inode#%"PRIu64" by "
+ "adding unsupported features.\n", j_blkno);
+ break;
+ case JOURNAL_MISS_FEATURE:
+ /* First of all, set all supported features for
+ * another journal file if existed, therefore, we
+ * easily let the journal file with current slotnum
+ * become features-missing when compared to the rest
+ * of journal files.
+ */
+ if (max_slots == 1)
+ FSWRK_FATAL("should specfiy a volume with multiple "
+ "slots to do this corruption\n");
+ else
+ adj_slotnum = (slotnum + 1 > max_slots - 1) ?
+ slotnum - 1 : slotnum + 1;
+
+ ret = ocfs2_malloc_block(fs->fs_io, &tmp_buf);
+ if (ret)
+ FSWRK_COM_FATAL(progname, ret);
+
+ ret = ocfs2_lookup_system_inode(fs, JOURNAL_SYSTEM_INODE,
+ adj_slotnum, &tmp_j_blkno);
+ if (ret)
+ FSWRK_COM_FATAL(progname, ret);
+
+ ret = ocfs2_read_cached_inode(fs, tmp_j_blkno, &tmp_ci);
+ if (ret)
+ FSWRK_COM_FATAL(progname, ret);
+
+ ret = ocfs2_extent_map_get_blocks(ci, 0, 1, &tmp_jsb_blkno,
+ &tmp_contig, NULL);
+ if (ret)
+ FSWRK_COM_FATAL(progname, ret);
+
+ ret = ocfs2_read_journal_superblock(fs, tmp_jsb_blkno, tmp_buf);
+ if (ret)
+ FSWRK_COM_FATAL(progname, ret);
+
+ tmp_jsb = (journal_superblock_t *)tmp_buf;
+
+ tmp_jsb->s_feature_compat |= JBD2_KNOWN_COMPAT_FEATURES;
+ tmp_jsb->s_feature_incompat |= JBD2_KNOWN_INCOMPAT_FEATURES;
+ tmp_jsb->s_feature_ro_compat |= JBD2_KNOWN_ROCOMPAT_FEATURES;
+
+ ret = ocfs2_write_journal_superblock(fs, tmp_jsb_blkno,
+ tmp_buf);
+ if (ret)
+ FSWRK_COM_FATAL(progname, ret);
+
+ if (tmp_buf)
+ ocfs2_free(&tmp_buf);
+ if (tmp_ci)
+ ocfs2_free_cached_inode(fs, tmp_ci);
+ /*
+ * Clear features bits for journal file with
+ * current slot number.
+ */
+ jsb->s_feature_compat &= ~JBD2_KNOWN_COMPAT_FEATURES;
+ jsb->s_feature_incompat &= ~JBD2_KNOWN_INCOMPAT_FEATURES;
+ jsb->s_feature_ro_compat &= ~JBD2_KNOWN_ROCOMPAT_FEATURES;
+ fprintf(stdout, "JOURNAL_FILE_INVALID: "
+ "Corrupt journal system inode#%"PRIu64" by "
+ "removing supported features.\n", j_blkno);
+ break;
+ case JOURNAL_TOO_SMALL:
+ old_no = ci->ci_inode->i_clusters;
+ ci->ci_inode->i_clusters = 0;
+ fprintf(stdout, "JOURNAL_FILE_INVALID: "
+ "Corrupt journal system inode#%"PRIu64"'s "
+ "i_clusters from %u to zero.\n", j_blkno, old_no);
+ break;
+ default:
+ FSWRK_FATAL("Invalid type[%d]\n", type);
+ }
+
+ ret = ocfs2_write_journal_superblock(fs, jsb_blkno, buf);
+ if (ret)
+ FSWRK_COM_FATAL(progname, ret);
+
+ ret = ocfs2_write_cached_inode(fs, ci);
+ if (ret)
+ FSWRK_COM_FATAL(progname, ret);
+
+ if (buf)
+ ocfs2_free(&buf);
+ if (ci)
+ ocfs2_free_cached_inode(fs, ci);
+
+ return;
+}
diff --git a/fswreck/main.c b/fswreck/main.c
index f69f1dc..73431ee 100644
--- a/fswreck/main.c
+++ b/fswreck/main.c
@@ -234,6 +234,14 @@ static struct prompt_code prompt_codes[NUM_FSCK_TYPE] = {
"Corrupt truncate log's tl_recs"),
define_prompt_code(TRUNCATE_REC_RANGE, corrupt_truncate_log,
"Corrupt truncate log's t_clusters"),
+ define_prompt_code(JOURNAL_FILE_INVALID, corrupt_sys_file,
+ "Corrupt journal file as an invalid one."),
+ define_prompt_code(JOURNAL_UNKNOWN_FEATURE, corrupt_sys_file,
+ "Corrupt journal file with unknown feature ."),
+ define_prompt_code(JOURNAL_MISS_FEATURE, corrupt_sys_file,
+ "Corrupt journal file by missing features."),
+ define_prompt_code(JOURNAL_TOO_SMALL, corrupt_sys_file,
+ "Corrupt journal file as a too small one."),
};
#undef define_prompt_code
--
1.5.5
More information about the Ocfs2-tools-devel
mailing list