X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=e2fsck%2Fproblem.c;h=0948bdbb5f575dde49d0b1ae8b2d5aa11316ed0d;hb=3faa5229cfc89cd82ed2b981366698cbecd5ee2b;hp=5825f5bcfd0480ffc7f99fa338090e7665c0834c;hpb=a6217f5ae2ca02f2f12c259b34615cbd7f4110d6;p=tools%2Fe2fsprogs.git diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 5825f5b..0948bdb 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #include @@ -353,7 +354,7 @@ static struct e2fsck_problem problem_table[] = { /* group descriptor N checksum is invalid. */ { PR_0_GDT_CSUM, - N_("@g descriptor %g checksum is invalid. "), + N_("@g descriptor %g checksum is %04x, should be %04y. "), PROMPT_FIX, PR_LATCH_BG_CHECKSUM }, /* group descriptor N marked uninitialized without feature set. */ @@ -361,11 +362,6 @@ static struct e2fsck_problem problem_table[] = { N_("@g descriptor %g marked uninitialized without feature set.\n"), PROMPT_FIX, PR_PREEN_OK }, - /* group N block bitmap uninitialized but inode bitmap in use. */ - { PR_0_BB_UNINIT_IB_INIT, - N_("@g %g @b @B uninitialized but @i @B in use.\n"), - PROMPT_FIX, PR_PREEN_OK }, - /* Group descriptor N has invalid unused inodes count. */ { PR_0_GDT_ITABLE_UNUSED, N_("@g descriptor %g has invalid unused inodes count %b. "), @@ -402,6 +398,41 @@ static struct e2fsck_problem problem_table[] = { N_("One or more @b @g descriptor checksums are invalid. "), PROMPT_FIX, PR_PREEN_OK }, + /* Free inodes count wrong */ + { PR_0_FREE_INODE_COUNT, + N_("Setting free @is count to %j (was %i)\n"), + PROMPT_NONE, PR_PREEN_NOMSG }, + + /* Free blocks count wrong */ + { PR_0_FREE_BLOCK_COUNT, + N_("Setting free @bs count to %c (was %b)\n"), + PROMPT_NONE, PR_PREEN_NOMSG }, + + /* Making quota file hidden */ + { PR_0_HIDE_QUOTA, + N_("Making @q @i %i (%Q) hidden.\n"), + PROMPT_NONE, PR_PREEN_OK }, + + /* Superblock has invalid MMP block. */ + { PR_0_MMP_INVALID_BLK, + N_("@S has invalid MMP block. "), + PROMPT_CLEAR, PR_PREEN_OK }, + + /* Superblock has invalid MMP magic. */ + { PR_0_MMP_INVALID_MAGIC, + N_("@S has invalid MMP magic. "), + PROMPT_FIX, PR_PREEN_OK | PR_NO_OK}, + + /* Opening file system failed */ + { PR_0_OPEN_FAILED, + N_("ext2fs_open2: %m\n"), + PROMPT_NONE, 0 }, + + /* Checking group descriptor failed */ + { PR_0_CHECK_DESC_FAILED, + N_("ext2fs_check_desc: %m\n"), + PROMPT_NONE, 0 }, + /* Pass 1 errors */ /* Pass 1: Checking inodes, blocks, and sizes */ @@ -885,11 +916,36 @@ static struct e2fsck_problem problem_table[] = { N_("@i %i has an invalid extent node (blk %b, lblk %c)\n"), PROMPT_CLEAR, 0 }, - { PR_1_EOFBLOCKS_FL_SET, - N_("@i %i should not have EOFBLOCKS_FL set " - "(size %Is, lblk %r)\n"), + /* Failed to convert subcluster bitmap */ + { PR_1_CONVERT_SUBCLUSTER, + N_("Error converting subcluster @b @B: %m\n"), + PROMPT_NONE, PR_FATAL }, + + /* Quota inode has bad mode */ + { PR_1_QUOTA_BAD_MODE, + N_("@q @i is not regular file. "), PROMPT_CLEAR, PR_PREEN_OK }, + /* Quota inode is not in use, but contains data */ + { PR_1_QUOTA_INODE_NOT_CLEAR, + N_("@q @i is not in use, but contains data. "), + PROMPT_CLEAR, PR_PREEN_OK }, + + /* Quota inode is user visible */ + { PR_1_QUOTA_INODE_NOT_HIDDEN, + N_("@q @i is visible to the user. "), + PROMPT_CLEAR, PR_PREEN_OK }, + + /* Invalid bad inode */ + { PR_1_INVALID_BAD_INODE, + N_("The bad @b @i looks @n. "), + PROMPT_CLEAR, 0 }, + + /* Extent has zero length */ + { PR_1_EXTENT_LENGTH_ZERO, + N_("@i %i has zero length extent\n\t(@n logical @b %c, physical @b %b)\n"), + PROMPT_CLEAR, 0 }, + /* Pass 1b errors */ /* Pass 1B: Rescan for duplicate/bad blocks */ @@ -933,7 +989,6 @@ static struct e2fsck_problem problem_table[] = { N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"), PROMPT_NONE, 0 }, - /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */ { PR_1C_PASS_HEADER, N_("Pass 1C: Scanning directories for @is with @m @bs\n"), @@ -1566,7 +1621,7 @@ static struct e2fsck_problem problem_table[] = { /* Free inodes count wrong */ { PR_5_FREE_INODE_COUNT, N_("Free @is count wrong (%i, counted=%j).\n"), - PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, + PROMPT_FIX, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG }, /* Free blocks count for group wrong */ { PR_5_FREE_BLOCK_COUNT_GROUP, @@ -1576,7 +1631,7 @@ static struct e2fsck_problem problem_table[] = { /* Free blocks count wrong */ { PR_5_FREE_BLOCK_COUNT, N_("Free @bs count wrong (%b, counted=%c).\n"), - PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, + PROMPT_FIX, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG }, /* Programming error: bitmap endpoints don't match */ { PR_5_BMAP_ENDPOINTS, @@ -1636,6 +1691,11 @@ static struct e2fsck_problem problem_table[] = { N_("Recreate @j"), PROMPT_NULL, PR_PREEN_OK | PR_NO_OK }, + /* Update quota information if it is inconsistent */ + { PR_6_UPDATE_QUOTAS, + N_("Update quota info for quota type %N"), + PROMPT_NULL, PR_PREEN_OK | PR_NO_OK }, + { 0 } }; @@ -1746,7 +1806,7 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) struct e2fsck_problem *ptr; struct latch_descr *ldesc = 0; const char *message; - int def_yn, answer, ans, broken_system_clock; + int def_yn, answer, ans; int print_answer = 0; int suppress = 0; @@ -1758,15 +1818,6 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) if (!(ptr->flags & PR_CONFIG)) { char key[9], *new_desc; - if ((code == PR_0_FUTURE_SB_LAST_MOUNT) || - (code == PR_0_FUTURE_SB_LAST_WRITE)) { - profile_get_boolean(ctx->profile, "options", - "broken_system_clock", 0, 0, - &broken_system_clock); - if (broken_system_clock) - ptr->flags |= PR_PREEN_OK; - } - sprintf(key, "0x%06x", code); profile_get_string(ctx->profile, "problems", key, @@ -1782,10 +1833,17 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) reconfigure_bool(ctx, ptr, key, PR_NOCOLLATE, "no_collate"); reconfigure_bool(ctx, ptr, key, PR_NO_NOMSG, "no_nomsg"); reconfigure_bool(ctx, ptr, key, PR_PREEN_NOHDR, "preen_noheader"); + reconfigure_bool(ctx, ptr, key, PR_FORCE_NO, "force_no"); + profile_get_integer(ctx->profile, "options", + "max_count_problems", 0, 0, + &ptr->max_count); + profile_get_integer(ctx->profile, "problems", key, "max_count", + ptr->max_count, &ptr->max_count); ptr->flags |= PR_CONFIG; } def_yn = 1; + ptr->count++; if ((ptr->flags & PR_NO_DEFAULT) || ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) || (ctx->options & E2F_OPT_NO)) @@ -1812,18 +1870,37 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) (ctx->options & E2F_OPT_PREEN)) suppress++; if ((ptr->flags & PR_NO_NOMSG) && - (ctx->options & E2F_OPT_NO)) + ((ctx->options & E2F_OPT_NO) || (ptr->flags & PR_FORCE_NO))) suppress++; + if (ptr->max_count && (ptr->count > ptr->max_count)) { + if (ctx->options & (E2F_OPT_NO | E2F_OPT_YES)) + suppress++; + if ((ctx->options & E2F_OPT_PREEN) && + (ptr->flags & PR_PREEN_OK)) + suppress++; + if ((ptr->flags & PR_LATCH_MASK) && + (ldesc->flags & (PRL_YES | PRL_NO))) + suppress++; + if (ptr->count == ptr->max_count + 1) { + printf("...problem 0x%06x suppressed\n", + ptr->e2p_code); + fflush(stdout); + } + } + message = ptr->e2p_description; + if (*message) + message = _(message); if (!suppress) { - message = ptr->e2p_description; if ((ctx->options & E2F_OPT_PREEN) && !(ptr->flags & PR_PREEN_NOHDR)) { printf("%s: ", ctx->device_name ? ctx->device_name : ctx->filesystem_name); } if (*message) - print_e2fsck_message(ctx, _(message), pctx, 1, 0); + print_e2fsck_message(stdout, ctx, message, pctx, 1, 0); } + if (ctx->logf && message) + print_e2fsck_message(ctx->logf, ctx, message, pctx, 1, 0); if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE)) preenhalt(ctx); @@ -1836,14 +1913,16 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) else answer = def_yn; } else { - if (ctx->options & E2F_OPT_PREEN) { + if (ptr->flags & PR_FORCE_NO) { + answer = 0; + print_answer = 1; + } else if (ctx->options & E2F_OPT_PREEN) { answer = def_yn; if (!(ptr->flags & PR_PREEN_NOMSG)) print_answer = 1; } else if ((ptr->flags & PR_LATCH_MASK) && (ldesc->flags & (PRL_YES | PRL_NO))) { - if (!suppress) - print_answer = 1; + print_answer = 1; if (ldesc->flags & PRL_YES) answer = 1; else @@ -1854,10 +1933,16 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) if (!answer && !(ptr->flags & PR_NO_OK)) ext2fs_unmark_valid(fs); - if (print_answer) - printf("%s.\n", answer ? - _(preen_msg[(int) ptr->prompt]) : _("IGNORED")); - + if (print_answer) { + if (!suppress) + printf("%s.\n", answer ? + _(preen_msg[(int) ptr->prompt]) : + _("IGNORED")); + if (ctx->logf) + fprintf(ctx->logf, "%s.\n", answer ? + _(preen_msg[(int) ptr->prompt]) : + _("IGNORED")); + } } if ((ptr->prompt == PROMPT_ABORT) && answer) @@ -1881,7 +1966,14 @@ profile_get_boolean(profile_t profile, const char *name, const char *subname, return 0; } -void print_e2fsck_message(e2fsck_t ctx, const char *msg, +errcode_t +profile_get_integer(profile_t profile, const char *name, const char *subname, + const char *subsubname, int def_val, int *ret_int) +{ + return 0; +} + +void print_e2fsck_message(FILE *f, e2fsck_t ctx, const char *msg, struct problem_context *pctx, int first, int recurse) { @@ -1947,6 +2039,7 @@ int main(int argc, char *argv[]) e2fsck_t ctx; int rc; + memset(&ctx, 0, sizeof(ctx)); /* just to quiet compiler */ rc = verify_problem_table(ctx); if (rc == 0) printf("e2fsck problem table verified\n");