[Ocfs2-tools-devel] [patch 9/9] Add journal check in fsck.ocfs2,
take 3
tao.ma at oracle.com
tao.ma at oracle.com
Wed Jun 20 00:22:07 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-06-19 13:43:27.000000000 -0400
+++ new.ocfs2-tools/fsck.ocfs2/journal.c 2007-06-19 13:44:00.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-06-19 13:43:27.000000000 -0400
+++ new.ocfs2-tools/fsck.ocfs2/fsck.c 2007-06-19 13:44:00.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-06-19 13:43:26.000000000 -0400
+++ new.ocfs2-tools/fsck.ocfs2/include/journal.h 2007-06-19 13:44:00.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