X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=e2fsck%2Fproblem.c;h=06640cbd6926c35fa9d31d50093c95e4fb68549f;hb=585545e1ee6288e2eafb02937b640301be4a1368;hp=fb9000717d7ec6db5f2e55dffc0b656637ba6007;hpb=44fe08f1fa1e9a994ff304aa02022c53c9341519;p=tools%2Fe2fsprogs.git diff --git a/e2fsck/problem.c b/e2fsck/problem.c index fb90007..06640cb 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,16 +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"), - PROMPT_CLEAR, PR_PREEN_OK }, - /* 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 */ @@ -938,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"), @@ -1571,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, @@ -1581,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, @@ -1641,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 } }; @@ -1734,11 +1789,11 @@ void clear_problem_context(struct problem_context *ctx) static void reconfigure_bool(e2fsck_t ctx, struct e2fsck_problem *ptr, const char *key, int mask, const char *name) { - int bool; + int val; - bool = (ptr->flags & mask); - profile_get_boolean(ctx->profile, "problems", key, name, bool, &bool); - if (bool) + val = (ptr->flags & mask); + profile_get_boolean(ctx->profile, "problems", key, name, val, &val); + if (val) ptr->flags |= mask; else ptr->flags &= ~mask; @@ -1779,10 +1834,16 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) 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)) @@ -1811,16 +1872,35 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) if ((ptr->flags & PR_NO_NOMSG) && ((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); @@ -1835,16 +1915,14 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) } else { if (ptr->flags & PR_FORCE_NO) { answer = 0; - if (!suppress) - print_answer = 1; + 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 @@ -1855,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) @@ -1882,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) { @@ -1948,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");