From d37066a9fa14ff3c0e7f4ea95e07204fce95f41a Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 21 Dec 2001 23:28:54 -0500 Subject: [PATCH] Give the opportunity for e2fsck to run the journal even if recovery flag is cleared. If we're using a backup superblock, run the journal by default. --- e2fsck/ChangeLog | 17 +++++++++++++++++ e2fsck/e2fsck.h | 1 + e2fsck/journal.c | 15 ++++++++++++++- e2fsck/problem.c | 28 ++++++++++++++++++++-------- e2fsck/problem.h | 14 ++++++++++---- e2fsck/unix.c | 6 +++--- 6 files changed, 65 insertions(+), 16 deletions(-) diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index cc55532..267bd55 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,20 @@ +2001-12-21 Theodore Tso + + * journal.c (e2fsck_check_ext3_journal): Give the opportunity to + run the journal even if recovery flag is cleared. If + we're using a backup superblock, run the journal by + default. + + * e2fsck.h (E2F_OPT_FORCE), unix.c (PRS, check_if_skip): Use a + bitfield in the e2fsck context flags word to indicate + whether or not a check should be forced. This allows the + journal code to set the option if necessary to force a + filesystem check. + + * problem.h, problem.c: Remove PR_0_JOURNAL_RESET_JOURNAL, and add + PR_0_JOURNAL_RUN and PR_0_JOURNAL_RUN_DEFAULT. Update + problem decription texts. + 2001-12-16 Theodore Tso * e2fsck.h (ext2fs_get_refcount_size), unix.c (check_mount, PRS), diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index 4898471..2cadfca 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -101,6 +101,7 @@ struct resource_track { #define E2F_OPT_TIME2 0x0020 #define E2F_OPT_CHECKBLOCKS 0x0040 #define E2F_OPT_DEBUG 0x0080 +#define E2F_OPT_FORCE 0x0100 /* * E2fsck flags diff --git a/e2fsck/journal.c b/e2fsck/journal.c index a07c7c1..9c9df54 100644 --- a/e2fsck/journal.c +++ b/e2fsck/journal.c @@ -598,6 +598,7 @@ int e2fsck_check_ext3_journal(e2fsck_t ctx) int recover = ctx->fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER; struct problem_context pctx; + problem_t problem; int reset = 0, force_fsck = 0; int retval; @@ -668,7 +669,19 @@ no_has_journal: if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL && !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) && journal->j_superblock->s_start != 0) { - if (fix_problem(ctx, PR_0_JOURNAL_RESET_JOURNAL, &pctx)) { + /* Print status information */ + fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx); + if (ctx->superblock) + problem = PR_0_JOURNAL_RUN_DEFAULT; + else + problem = PR_0_JOURNAL_RUN; + if (fix_problem(ctx, problem, &pctx)) { + ctx->options |= E2F_OPT_FORCE; + sb->s_feature_incompat |= + EXT3_FEATURE_INCOMPAT_RECOVER; + ext2fs_mark_super_dirty(ctx->fs); + } else if (fix_problem(ctx, + PR_0_JOURNAL_RESET_JOURNAL, &pctx)) { reset = 1; sb->s_state &= ~EXT2_VALID_FS; ext2fs_mark_super_dirty(ctx->fs); diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 58b8724..3a069d0 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -38,6 +38,7 @@ #define PROMPT_DELETE 15 #define PROMPT_SUPPRESS 16 #define PROMPT_UNLINK 17 +#define PROMPT_NULL 18 /* * These are the prompts which are used to ask the user if they want @@ -62,6 +63,7 @@ static const char *prompt[] = { N_("Delete file"), /* 15 */ N_("Suppress messages"),/* 16 */ N_("Unlink"), /* 17 */ + "", /* 18 */ }; /* @@ -214,7 +216,7 @@ static const struct e2fsck_problem problem_table[] = { /* Superblock flag should be cleared */ { PR_0_JOURNAL_HAS_JOURNAL, - N_("@S doesn't have has_journal flag, but has ext3 @j %s.\n"), + N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"), PROMPT_CLEAR, PR_PREEN_OK }, /* Superblock flag is incorrect */ @@ -222,15 +224,25 @@ static const struct e2fsck_problem problem_table[] = { N_("@S has ext3 needs_recovery flag set, but no @j.\n"), PROMPT_CLEAR, PR_PREEN_OK }, - /* Journal should be reset */ + /* Journal has data, but recovery flag is clear */ + { PR_0_JOURNAL_RECOVERY_CLEAR, + N_("ext3 recovery flag clear, but @j has data.\n"), + PROMPT_NONE, 0 }, + + /* Ask if we should clear the journal */ { PR_0_JOURNAL_RESET_JOURNAL, - N_("*** WARNING *** leaving data in the @j may be DANGEROUS.\n"), - PROMPT_NONE, PR_PREEN_NOMSG|PR_AFTER_CODE, PR_0_JOURNAL_RESET_PROMPT}, + N_("Clear @j"), + PROMPT_NULL, PR_PREEN_NOMSG }, - /* Journal should be reset */ - { PR_0_JOURNAL_RESET_PROMPT, - N_("ext3 recovery flag clear, but journal has data.\n"), - PROMPT_CLEAR, PR_PREEN_OK|PR_PREEN_NOMSG }, + /* Ask if we should run the journal anyway */ + { PR_0_JOURNAL_RUN, + N_("Run @j anyway"), + PROMPT_NULL, 0 }, + + /* Run the journal by default */ + { PR_0_JOURNAL_RUN_DEFAULT, + N_("Recovery flag not set in backup @S, so running @j anyway.\n"), + PROMPT_NONE, 0 }, /* Clearing orphan inode */ { PR_0_ORPHAN_CLEAR_INODE, diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 6a234b7..fbbb393 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -122,11 +122,11 @@ struct problem_context { /* Superblock has recovery flag set but no journal */ #define PR_0_JOURNAL_RECOVER_SET 0x000017 -/* Warning message about leaving data in the journal */ -#define PR_0_JOURNAL_RESET_JOURNAL 0x000018 +/* Journal has data, but recovery flag is clear */ +#define PR_0_JOURNAL_RECOVERY_CLEAR 0x000018 -/* Superblock recovery flag clear - journal needs to be reset */ -#define PR_0_JOURNAL_RESET_PROMPT 0x000019 +/* Ask if we should clear the journal */ +#define PR_0_JOURNAL_RESET_JOURNAL 0x000019 /* Filesystem revision is 0, but feature flags are set */ #define PR_0_FS_REV_LEVEL 0x00001A @@ -164,6 +164,12 @@ struct problem_context { /* Clearing V2 journal superblock */ #define PR_0_CLEAR_V2_JOURNAL 0x00002A +/* Run journal anyway */ +#define PR_0_JOURNAL_RUN 0x00002B + +/* Run journal anyway by default */ +#define PR_0_JOURNAL_RUN_DEFAULT 0x00002C + /* * Pass 1 errors */ diff --git a/e2fsck/unix.c b/e2fsck/unix.c index 61f7377..e811df6 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -47,7 +47,6 @@ static int swapfs = 0; static int normalize_swapfs = 0; static int cflag = 0; /* check disk */ static int show_version_only = 0; -static int force = 0; static int verbose = 0; static int replace_bad_blocks = 0; @@ -253,7 +252,8 @@ static void check_if_skip(e2fsck_t ctx) const char *reason = NULL; unsigned int reason_arg = 0; - if (force || bad_blocks_file || cflag || swapfs) + if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file || + cflag || swapfs) return; if (fs->super->s_state & EXT2_ERROR_FS) @@ -547,7 +547,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) ctx->options |= E2F_OPT_DEBUG; break; case 'f': - force = 1; + ctx->options |= E2F_OPT_FORCE; break; case 'F': flush = 1; -- 1.8.3.1