[Ocfs2-tools-devel] [patch 9/9] Add journal check in fsck.ocfs2, take 4

tao.ma at oracle.com tao.ma at oracle.com
Wed Jul 11 02:10:34 PDT 2007


In an unsuccessful slot remove, we may empty its content or truncate its size.
And a slot can't be used unless it has a health journal file, so check it
and recreate the journal file if needed.

Index: new.ocfs2-tools/fsck.ocfs2/journal.c
===================================================================
--- new.ocfs2-tools.orig/fsck.ocfs2/journal.c	2007-07-10 16:35:20.000000000 -0400
+++ new.ocfs2-tools/fsck.ocfs2/journal.c	2007-07-10 16:36:36.000000000 -0400
@@ -735,3 +735,87 @@ out:
 
 	return ret;
 }
+
+static errcode_t check_journal_super(ocfs2_filesys *fs,
+				     ocfs2_cached_inode *ci)
+{
+	errcode_t ret;
+	int contig;
+	uint64_t blkno;
+	char *buf = NULL;
+
+	ret = ocfs2_malloc_blocks(fs->fs_io, 1, &buf);
+	if (ret)
+		goto out;
+
+	ret = ocfs2_extent_map_init(fs, ci);
+	if (ret)
+		goto out;
+
+	ret = ocfs2_extent_map_get_blocks(ci, 0, 1, &blkno, &contig);
+	if (ret)
+		goto out;
+
+	ret = ocfs2_read_journal_superblock(fs, blkno, buf);
+out:
+	return ret;
+}
+
+/* When we remove slot in tunefs.ocfs2, there may be some panic and
+ * we may corrupt some journal files, so we have to check whether the
+ * journal file is corrupted and recreate it.
+ */
+errcode_t o2fsck_check_journals(o2fsck_state *ost)
+{
+	errcode_t ret = 0;
+	uint64_t blkno;
+	uint32_t num_clusters = 0;
+	ocfs2_filesys *fs = ost->ost_fs;
+	char fname[OCFS2_MAX_FILENAME_LEN];
+	uint16_t i, max_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
+	ocfs2_cached_inode *ci = NULL;
+
+	for (i = 0; i < max_slots; i++) {
+		ret = ocfs2_lookup_system_inode(fs, JOURNAL_SYSTEM_INODE, i,
+						&blkno);
+		if (ret)
+			goto out;
+
+		ret = ocfs2_read_cached_inode(fs, blkno, &ci);
+		if (ret)
+			goto out;
+
+		if (ci->ci_inode->i_clusters > 0) {
+			/* check whether the file contains valid super block. */
+			ret = check_journal_super(fs, ci);
+			if (!ret) {
+				/* record the valid cluster size. */
+				num_clusters = ci->ci_inode->i_clusters;
+				continue;
+			}
+		}
+
+		if (num_clusters == 0) {
+			/* none of the journal is valid, servere errors. */
+			ret = OCFS2_ET_JOURNAL_TOO_SMALL;
+			goto out;
+		}
+
+		sprintf(fname,
+			ocfs2_system_inodes[JOURNAL_SYSTEM_INODE].si_name, i);
+		if (!prompt(ost, PY, PR_JOURNAL_FILE_INVALID,
+			    "journal file %s is invalid, regenerate it?",
+			    fname))
+			continue;
+
+		ret = ocfs2_make_journal(fs, blkno, num_clusters);
+		if (ret)
+			goto out;
+	}
+
+out:
+	if (ci)
+		ocfs2_free_cached_inode(fs, ci);
+	return ret;
+}
+
Index: new.ocfs2-tools/fsck.ocfs2/fsck.c
===================================================================
--- new.ocfs2-tools.orig/fsck.ocfs2/fsck.c	2007-07-10 16:35:20.000000000 -0400
+++ new.ocfs2-tools/fsck.ocfs2/fsck.c	2007-07-10 16:36:36.000000000 -0400
@@ -182,6 +182,12 @@ static errcode_t write_out_superblock(o2
 	if (sb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_RESIZE_INPROG)
 		sb->s_feature_incompat &= ~OCFS2_FEATURE_INCOMPAT_RESIZE_INPROG;
 
+	if (sb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_TUNEFS_INPROG) {
+		sb->s_feature_incompat &=
+				 ~OCFS2_FEATURE_INCOMPAT_TUNEFS_INPROG;
+		sb->s_tunefs_flag = 0;
+	}
+
 	if (ost->ost_num_clusters)
 		di->i_clusters = ost->ost_num_clusters;
 
@@ -262,6 +268,9 @@ static int fs_is_clean(o2fsck_state *ost
 	else if ((OCFS2_RAW_SB(ost->ost_fs->fs_super)->s_feature_incompat &
 		  OCFS2_FEATURE_INCOMPAT_RESIZE_INPROG))
 		strcpy(reason, "incomplete volume resize detected");
+	else if ((OCFS2_RAW_SB(ost->ost_fs->fs_super)->s_feature_incompat &
+		  OCFS2_FEATURE_INCOMPAT_TUNEFS_INPROG))
+		strcpy(reason, "incomplete tunefs operation detected");
 	else if (sb->s_state & OCFS2_ERROR_FS)
 		strcpy(reason, "contains a file system with errors");
 	else if (sb->s_max_mnt_count > 0 &&
@@ -655,6 +664,15 @@ int main(int argc, char **argv)
 	printf("  max slots:          %u\n\n", 
 	       OCFS2_RAW_SB(ost->ost_fs->fs_super)->s_max_slots);
 
+	if (open_flags & OCFS2_FLAG_RW) {
+		ret = o2fsck_check_journals(ost);
+		if (ret) {
+			printf("fsck saw unrecoverable errors in the journal "
+				"files and will not continue.\n");
+			goto unlock;
+		}
+	}
+
 	ret = maybe_replay_journals(ost, filename, open_flags, blkno, blksize);
 	if (ret) {
 		printf("fsck encountered unrecoverable errors while "
Index: new.ocfs2-tools/fsck.ocfs2/include/journal.h
===================================================================
--- new.ocfs2-tools.orig/fsck.ocfs2/include/journal.h	2007-07-10 16:35:20.000000000 -0400
+++ new.ocfs2-tools/fsck.ocfs2/include/journal.h	2007-07-10 16:36:36.000000000 -0400
@@ -28,6 +28,7 @@
 
 errcode_t o2fsck_replay_journals(ocfs2_filesys *fs, int *replayed);
 errcode_t o2fsck_should_replay_journals(ocfs2_filesys *fs, int *should);
+errcode_t o2fsck_check_journals(o2fsck_state *ost);
 
 #endif /* __O2FSCK_JOURNAL_H__ */
 

-- 



More information about the Ocfs2-tools-devel mailing list