X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=e2fsck%2Fproblem.c;h=25df7ede2569dedb22462b83c1671aefaba943d4;hb=26bd022c5c57c29da6bb1bc14c9d2fcf19018f32;hp=1b09b63d5de8b9c0e39c46727435308629aae97e;hpb=60139154878ebdafd4b372cdcf179c5a957c519d;p=tools%2Fe2fsprogs.git diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 1b09b63..25df7ed 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -9,6 +9,7 @@ * %End-Header% */ +#include "config.h" #include #include #include @@ -252,12 +253,12 @@ static struct e2fsck_problem problem_table[] = { /* Illegal block found in orphaned inode */ { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, - N_("@I @b #%B (%b) found in @o @i %i.\n"), + N_("@I %B (%b) found in @o @i %i.\n"), PROMPT_NONE, 0 }, /* Already cleared block found in orphaned inode */ { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, - N_("Already cleared @b #%B (%b) found in @o @i %i.\n"), + N_("Already cleared %B (%b) found in @o @i %i.\n"), PROMPT_NONE, 0 }, /* Illegal orphan inode in superblock */ @@ -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. "), @@ -388,13 +384,13 @@ static struct e2fsck_problem problem_table[] = { /* Last mount time is in the future (fudged) */ { PR_0_FUTURE_SB_LAST_MOUNT_FUDGED, N_("@S last mount time is in the future.\n\t(by less than a day, " - "probably due to buggy init scripts) "), + "probably due to the hardware clock being incorrectly set) "), PROMPT_FIX, PR_PREEN_OK | PR_NO_OK }, /* Last write time is in the future (fudged) */ { PR_0_FUTURE_SB_LAST_WRITE_FUDGED, N_("@S last write time is in the future.\n\t(by less than a day, " - "probably due to buggy init scripts). "), + "probably due to the hardware clock being incorrectly set). "), PROMPT_FIX, PR_PREEN_OK | PR_NO_OK }, /* Block group checksum (latch question) is invalid. */ @@ -402,6 +398,54 @@ 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 }, + + { PR_0_MIN_EXTRA_ISIZE_INVALID, + N_("@S has invalid s_min_extra_isize. "), + PROMPT_FIX, PR_PREEN_OK }, + + { PR_0_WANT_EXTRA_ISIZE_INVALID, + N_("@S has invalid s_want_extra_isize. "), + PROMPT_FIX, PR_PREEN_OK }, + + { PR_0_CLEAR_EXTRA_ISIZE, + N_("Disable extra_isize feature since @f has 128 byte inodes.\n"), + PROMPT_NONE, 0 }, + + /* Pass 1 errors */ /* Pass 1: Checking inodes, blocks, and sizes */ @@ -475,12 +519,12 @@ static struct e2fsck_problem problem_table[] = { /* Illegal blocknumber in inode */ { PR_1_ILLEGAL_BLOCK_NUM, - N_("@I @b #%B (%b) in @i %i. "), + N_("@I %B (%b) in @i %i. "), PROMPT_CLEAR, PR_LATCH_BLOCK }, /* Block number overlaps fs metadata */ { PR_1_BLOCK_OVERLAPS_METADATA, - N_("@b #%B (%b) overlaps @f metadata in @i %i. "), + N_("%B (%b) overlaps @f metadata in @i %i. "), PROMPT_CLEAR, PR_LATCH_BLOCK }, /* Inode has illegal blocks (latch question) */ @@ -495,7 +539,7 @@ static struct e2fsck_problem problem_table[] = { /* Illegal block number in bad block inode */ { PR_1_BB_ILLEGAL_BLOCK_NUM, - N_("@I @b #%B (%b) in bad @b @i. "), + N_("@I %B (%b) in bad @b @i. "), PROMPT_CLEAR, PR_LATCH_BBLOCK }, /* Bad block inode has illegal blocks (latch question) */ @@ -703,17 +747,17 @@ static struct e2fsck_problem problem_table[] = { /* Error reading Extended Attribute block while fixing refcount */ { PR_1_EXTATTR_READ_ABORT, N_("Error reading @a @b %b (%m). "), - PROMPT_ABORT, 0 }, + PROMPT_NONE, PR_FATAL }, /* Extended attribute reference count incorrect */ { PR_1_EXTATTR_REFCOUNT, - N_("@a @b %b has reference count %B, @s %N. "), + N_("@a @b %b has reference count %r, @s %N. "), PROMPT_FIX, 0 }, /* Error writing Extended Attribute block while fixing refcount */ - { PR_1_EXTATTR_WRITE, + { PR_1_EXTATTR_WRITE_ABORT, N_("Error writing @a @b %b (%m). "), - PROMPT_ABORT, 0 }, + PROMPT_NONE, PR_FATAL }, /* Multiple EA blocks not supported */ { PR_1_EA_MULTI_BLOCK, @@ -721,9 +765,9 @@ static struct e2fsck_problem problem_table[] = { PROMPT_CLEAR, 0}, /* Error allocating EA region allocation structure */ - { PR_1_EA_ALLOC_REGION, + { PR_1_EA_ALLOC_REGION_ABORT, N_("@A @a @b %b. "), - PROMPT_ABORT, 0}, + PROMPT_NONE, PR_FATAL}, /* Error EA allocation collision */ { PR_1_EA_ALLOC_COLLISION, @@ -746,17 +790,17 @@ static struct e2fsck_problem problem_table[] = { /* Directory too big */ { PR_1_TOOBIG_DIR, - N_("@b #%B (%b) causes @d to be too big. "), + N_("%B (%b) causes @d to be too big. "), PROMPT_CLEAR, PR_LATCH_TOOBIG }, /* Regular file too big */ { PR_1_TOOBIG_REG, - N_("@b #%B (%b) causes file to be too big. "), + N_("%B (%b) causes file to be too big. "), PROMPT_CLEAR, PR_LATCH_TOOBIG }, /* Symlink too big */ { PR_1_TOOBIG_SYMLINK, - N_("@b #%B (%b) causes symlink to be too big. "), + N_("%B (%b) causes symlink to be too big. "), PROMPT_CLEAR, PR_LATCH_TOOBIG }, /* INDEX_FL flag set on a non-HTREE filesystem */ @@ -798,7 +842,7 @@ static struct e2fsck_problem problem_table[] = { /* Resize inode failed */ { PR_1_RESIZE_INODE_CREATE, N_("Resize @i (re)creation failed: %m."), - PROMPT_ABORT, 0 }, + PROMPT_CONTINUE, 0 }, /* invalid inode->i_extra_isize */ { PR_1_EXTRA_ISIZE, @@ -885,6 +929,73 @@ static struct e2fsck_problem problem_table[] = { N_("@i %i has an invalid extent node (blk %b, lblk %c)\n"), PROMPT_CLEAR, 0 }, + /* 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 }, + + /* Bad extended attribute value in inode */ + { PR_1_INODE_EA_BAD_VALUE, + N_("@a in @i %i is corrupt (@n value)."), + PROMPT_CLEAR, 0}, + + /* expand inode */ + { PR_1_EXPAND_EISIZE_WARNING, + N_("\ne2fsck is being run with \"expand_extra_isize\" option or\n" + "s_min_extra_isize of %d bytes has been set in the superblock.\n" + "Inode %i does not have enough free space. Either some EAs\n" + "need to be deleted from this inode or the RO_COMPAT_EXTRA_ISIZE\n" + "flag must be cleared.\n\n"), PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | + PR_PREEN_NOMSG }, + + /* expand inode */ + { PR_1_EXPAND_EISIZE, + N_("Expanding @i %i.\n"), + PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG }, + + /* delete an EA so that EXTRA_ISIZE feature may be enabled */ + { PR_1_EISIZE_DELETE_EA, + N_("Delete EA %s of @i %i so that EXTRA_ISIZE feature may be " + "enabled?\n"), PROMPT_FIX, PR_NO_OK | PR_PREEN_NO }, + + /* an EA needs to be deleted by e2fsck is being run with -p or -y */ + { PR_1_EA_BLK_NOSPC, + N_("An EA needs to be deleted for @i %i but e2fsck is being run\n" + "with -p or -y mode.\n"), + PROMPT_ABORT, 0 }, + + /* disable EXTRA_ISIZE feature since inode cannot be expanded */ + { PR_1_CLEAR_EXTRA_ISIZE, + N_("Disable EXTRA_ISIZE feature since @i %i cannot be expanded\n" + "without deletion of an EA.\n"), + PROMPT_FIX, 0 }, + + /* Pass 1b errors */ /* Pass 1B: Rescan for duplicate/bad blocks */ @@ -928,7 +1039,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"), @@ -943,7 +1053,7 @@ static struct e2fsck_problem problem_table[] = { /* File has duplicate blocks */ { PR_1D_DUP_FILE, N_("File %Q (@i #%i, mod time %IM) \n" - " has %B @m @b(s), shared with %N file(s):\n"), + " has %r @m @b(s), shared with %N file(s):\n"), PROMPT_NONE, 0 }, /* List of files sharing duplicate blocks */ @@ -978,6 +1088,14 @@ static struct e2fsck_problem problem_table[] = { { PR_1D_CLONE_ERROR, N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 }, + /* File with shared blocks found */ + { PR_1D_DISCONNECT_QUESTION, + N_("File with shared blocks found\n"), PROMPT_CONNECT, 0 }, + + /* Couldn't unlink file (error) */ + { PR_1D_DISCONNECT_ERROR, + N_("Couldn't unlink file: %m\n"), PROMPT_NONE, 0 }, + /* Pass 2 errors */ /* Pass 2: Checking directory structure */ @@ -1077,17 +1195,17 @@ static struct e2fsck_problem problem_table[] = { /* directory corrupted */ { PR_2_DIR_CORRUPTED, - N_("@d @i %i, @b %B, offset %N: @d corrupted\n"), + N_("@d @i %i, %B, offset %N: @d corrupted\n"), PROMPT_SALVAGE, 0 }, /* filename too long */ { PR_2_FILENAME_LONG, - N_("@d @i %i, @b %B, offset %N: filename too long\n"), + N_("@d @i %i, %B, offset %N: filename too long\n"), PROMPT_TRUNCATE, 0 }, /* Directory inode has a missing block (hole) */ { PR_2_DIRECTORY_HOLE, - N_("@d @i %i has an unallocated @b #%B. "), + N_("@d @i %i has an unallocated %B. "), PROMPT_ALLOCATE, 0 }, /* '.' is not NULL terminated */ @@ -1212,22 +1330,22 @@ static struct e2fsck_problem problem_table[] = { /* Node in HTREE directory not referenced */ { PR_2_HTREE_NOTREF, - N_("@p @h %d: node (%B) not referenced\n"), + N_("@p @h %d: %B not referenced\n"), PROMPT_NONE, 0 }, /* Node in HTREE directory referenced twice */ { PR_2_HTREE_DUPREF, - N_("@p @h %d: node (%B) referenced twice\n"), + N_("@p @h %d: %B referenced twice\n"), PROMPT_NONE, 0 }, /* Node in HTREE directory has bad min hash */ { PR_2_HTREE_MIN_HASH, - N_("@p @h %d: node (%B) has bad min hash\n"), + N_("@p @h %d: %B has bad min hash\n"), PROMPT_NONE, 0 }, /* Node in HTREE directory has bad max hash */ { PR_2_HTREE_MAX_HASH, - N_("@p @h %d: node (%B) has bad max hash\n"), + N_("@p @h %d: %B has bad max hash\n"), PROMPT_NONE, 0 }, /* Clear invalid HTREE directory */ @@ -1251,22 +1369,22 @@ static struct e2fsck_problem problem_table[] = { /* Invalid HTREE limit */ { PR_2_HTREE_BAD_LIMIT, - N_("@p @h %d: node (%B) has @n limit (%N)\n"), + N_("@p @h %d: %B has @n limit (%N)\n"), PROMPT_CLEAR_HTREE, PR_PREEN_OK }, /* Invalid HTREE count */ { PR_2_HTREE_BAD_COUNT, - N_("@p @h %d: node (%B) has @n count (%N)\n"), + N_("@p @h %d: %B has @n count (%N)\n"), PROMPT_CLEAR_HTREE, PR_PREEN_OK }, /* HTREE interior node has out-of-order hashes in table */ { PR_2_HTREE_HASH_ORDER, - N_("@p @h %d: node (%B) has an unordered hash table\n"), + N_("@p @h %d: %B has an unordered hash table\n"), PROMPT_CLEAR_HTREE, PR_PREEN_OK }, /* Node in HTREE directory has invalid depth */ { PR_2_HTREE_BAD_DEPTH, - N_("@p @h %d: node (%B) has @n depth (%N)\n"), + N_("@p @h %d: %B has @n depth (%N)\n"), PROMPT_NONE, 0 }, /* Duplicate directory entry found */ @@ -1561,7 +1679,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, @@ -1571,7 +1689,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, @@ -1624,6 +1742,11 @@ static struct e2fsck_problem problem_table[] = { N_("@g %g @i(s) in use but @g is marked INODE_UNINIT\n"), PROMPT_FIX, PR_PREEN_OK }, + /* Expand inode */ + { PR_5_EXPAND_EISIZE, + N_("Expanding @i %i.\n"), + PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG }, + /* Post-Pass 5 errors */ /* Recreate journal if E2F_FLAG_JOURNAL_INODE flag is set */ @@ -1631,6 +1754,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 } }; @@ -1768,10 +1896,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)) @@ -1798,18 +1933,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); @@ -1822,14 +1976,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 @@ -1840,10 +1996,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) @@ -1867,7 +2029,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) { @@ -1933,6 +2102,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");