* %End-Header%
*/
+#include "config.h"
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
/* 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. */
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. "),
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 */
/* 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,
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,
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,
/* 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,
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 */
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"),
{ 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 */
/* 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,
/* 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,
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 */
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 }
};
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))
(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);
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
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)
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)
{
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");