[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