From: Theodore Ts'o Date: Fri, 10 Mar 2006 20:25:59 +0000 (-0500) Subject: Enhance e2fsck so it can fix external journal hint in the superblock X-Git-Tag: E2FSPROGS-1.39-WIP-0330~36 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b1c52b26a44efeb366402985763c242a4b21aeb1;p=thirdparty%2Fe2fsprogs.git Enhance e2fsck so it can fix external journal hint in the superblock Check to see if the superblock hint for the external journal needs to be updated, and if so, offer to update it. (Addresses Debian Bug: #355644) Signed-off-by: "Theodore Ts'o" --- diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index a2bfcf981..7facefa84 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,12 @@ +2006-03-10 Theodore Ts'o + + * e2fsck.h, journal.c (e2fsck_fix_ext3_journal_hint), + problem.c (PR_0_EXTERNAL_JOURNAL_HINT), + problem.h (PR_0_EXTERNAL_JOURNAL_HINT), super.c: Check + to see if the superblock hint for the external journal + needs to be updated, and if so, offer to update it. + (Addresses Debian Bug: #355644) + 2006-01-29 Theodore Ts'o * unix.c (check_if_skip): When skipping a check due to being on diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index be7899ffc..30ff8589c 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -406,6 +406,7 @@ extern void ehandler_init(io_channel channel); extern int e2fsck_check_ext3_journal(e2fsck_t ctx); extern int e2fsck_run_ext3_journal(e2fsck_t ctx); extern void e2fsck_move_ext3_journal(e2fsck_t ctx); +extern int e2fsck_fix_ext3_journal_hint(e2fsck_t ctx); /* pass1.c */ extern void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool); diff --git a/e2fsck/journal.c b/e2fsck/journal.c index 0a53cc7a8..a5ebe1420 100644 --- a/e2fsck/journal.c +++ b/e2fsck/journal.c @@ -959,3 +959,40 @@ err_out: return; } +/* + * This function makes sure the superblock hint for the external + * journal is correct. + */ +int e2fsck_fix_ext3_journal_hint(e2fsck_t ctx) +{ + struct ext2_super_block *sb = ctx->fs->super; + struct problem_context pctx; + char uuid[37], *journal_name; + struct stat st; + problem_t problem; + int retval; + + if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) || + uuid_is_null(sb->s_journal_uuid)) + return 0; + + uuid_unparse(sb->s_journal_uuid, uuid); + journal_name = blkid_get_devname(ctx->blkid, "UUID", uuid); + if (!journal_name) + return 0; + + if (stat(journal_name, &st) < 0) + return 0; + + if (st.st_rdev != sb->s_journal_dev) { + clear_problem_context(&pctx); + pctx.num = st.st_rdev; + if (fix_problem(ctx, PR_0_EXTERNAL_JOURNAL_HINT, &pctx)) { + sb->s_journal_dev = st.st_rdev; + ext2fs_mark_super_dirty(ctx->fs); + } + } + + free(journal_name); + return 0; +} diff --git a/e2fsck/problem.c b/e2fsck/problem.c index a25cc088e..2dc3073ae 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -342,6 +342,10 @@ static struct e2fsck_problem problem_table[] = { N_("@S last write time is in the future. "), PROMPT_FIX, PR_PREEN_OK }, + { PR_0_EXTERNAL_JOURNAL_HINT, + N_("@S hint for external superblock @s %X. "), + PROMPT_FIX, PR_PREEN_OK }, + /* Pass 1 errors */ /* Pass 1: Checking inodes, blocks, and sizes */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 9614d1cc1..12f29ec0a 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -190,6 +190,9 @@ struct problem_context { /* Last write time is in the future */ #define PR_0_FUTURE_SB_LAST_WRITE 0x000032 +/* Superblock hint for external journal incorrect */ +#define PR_0_EXTERNAL_JOURNAL_HINT 0x000033 + /* * Pass 1 errors */ diff --git a/e2fsck/super.c b/e2fsck/super.c index d886bbd1c..2e7607ced 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -728,5 +728,11 @@ void check_super_block(e2fsck_t ctx) * Move the ext3 journal file, if necessary. */ e2fsck_move_ext3_journal(ctx); + + /* + * Fix journal hint, if necessary + */ + e2fsck_fix_ext3_journal_hint(ctx); + return; }