From b1c52b26a44efeb366402985763c242a4b21aeb1 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 10 Mar 2006 15:25:59 -0500 Subject: [PATCH] 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" --- e2fsck/ChangeLog | 9 +++++++++ e2fsck/e2fsck.h | 1 + e2fsck/journal.c | 37 +++++++++++++++++++++++++++++++++++++ e2fsck/problem.c | 4 ++++ e2fsck/problem.h | 3 +++ e2fsck/super.c | 6 ++++++ 6 files changed, 60 insertions(+) diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index a2bfcf9..7facefa 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 be7899f..30ff858 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 0a53cc7..a5ebe14 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 a25cc08..2dc3073 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 9614d1c..12f29ec 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 d886bbd..2e7607c 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; } -- 1.8.3.1