[Ocfs2-tools-devel] [PATCH 3/3] Ocfs2-tools: Implement new prompt codes of journal for fswreck.

Tristan Ye tristan.ye at oracle.com
Tue Jun 30 21:58:06 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 |   14 +++-
 fswreck/include/journal.h   |   30 +++++++
 fswreck/include/main.h      |    1 +
 fswreck/journal.c           |  178 +++++++++++++++++++++++++++++++++++++++++++
 fswreck/main.c              |    8 ++
 7 files changed, 240 insertions(+), 6 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 c7b9170..df3cbc0 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
 };
 
@@ -154,7 +158,8 @@ enum fsck_type
  * Group list error: GROUP_UNEXPECTED_DESC, GROUP_EXPECTED_DESC
  *
  * Inode field error: 	INODE_SUBALLOC, INODE_GEN, INODE_GEN_FIX,INODE_BLKNO,
-			INODE_NZ_DTIME, INODE_SIZE, INODE_CLUSTERS, INODE_COUNT
+ *			INODE_NZ_DTIME, INODE_SIZE, INODE_SPARSE_SIZE,
+ *			INODE_CLUSTERS, INODE_SPARSE_CLUSTERS, INODE_COUNT
  *
  * Inode link not connected error: INODE_LINK_NOT_CONNECTED 
  *
@@ -178,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
  *
@@ -194,9 +201,8 @@ enum fsck_type
  *
  * Directory not connected error: DIR_NOT_CONNECTED
  *
- * Inline file flag error:	INLINE_DATA_FLAG_INVALID
- *
- * Inline file id_count error:  INLINE_DATA_COUNT_INVALID
+ * Inline file:	INLINE_DATA_FLAG_INVALID, INLINE_DATA_COUNT_INVALID,
+ *		INODE_INLINE_SIZE, INODE_INLINE_CLUSTERS
  *
  */
 #endif
diff --git a/fswreck/include/journal.h b/fswreck/include/journal.h
new file mode 100644
index 0000000..f948ba1
--- /dev/null
+++ b/fswreck/include/journal.h
@@ -0,0 +1,30 @@
+/*
+ * journal.h
+ *
+ * Function prototypes, macros, etc. for related 'C' files
+ *
+ * Copyright (C) 2009 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 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.
+ *
+ */
+
+#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..3f2c6d9
--- /dev/null
+++ b/fswreck/journal.c
@@ -0,0 +1,178 @@
+/*
+ * journal.c
+ *
+ * corruptions for journal file.
+ *
+ * Copyright (C) 2009 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 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.
+ *
+ */
+
+#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 = htonl(JBD2_MAGIC_NUMBER);
+		jsb->s_header.h_magic = ~htonl(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, !htonl(JBD2_MAGIC_NUMBER));
+		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)
+			adj_slotnum = slotnum;
+		else
+			adj_slotnum = (slotnum + 1 > max_slots - 1) ?
+				       max_slots - 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_cached_inode(fs, ci);
+	if (ret)
+		FSWRK_COM_FATAL(progname, ret);
+
+	ret = ocfs2_write_journal_superblock(fs, jsb_blkno, buf);
+	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