* %End-Header%
*/
+#include "config.h"
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
/* Superblock corrupt */
{ PR_0_SB_CORRUPT,
- N_("\nThe @S could not be read or does not describe a correct ext2\n"
- "@f. If the @v is valid and it really contains an ext2\n"
+ N_("\nThe @S could not be read or does not describe a valid ext2/ext3/ext4\n"
+ "@f. If the @v is valid and it really contains an ext2/ext3/ext4\n"
"@f (and not swap or ufs or something else), then the @S\n"
"is corrupt, and you might try running e2fsck with an alternate @S:\n"
- " e2fsck -b %S <@v>\n\n"),
- PROMPT_NONE, PR_FATAL },
+ " e2fsck -b 8193 <@v>\n"
+ " or\n"
+ " e2fsck -b 32768 <@v>\n\n"),
+ PROMPT_NONE, 0 },
/* Filesystem size is wrong */
{ PR_0_FS_SIZE_WRONG,
/* Superblock has_journal flag is clear but has a journal */
{ PR_0_JOURNAL_HAS_JOURNAL,
- N_("@S has_@j flag is clear, but a @j %s is present.\n"),
+ N_("@S has_@j flag is clear, but a @j is present.\n"),
PROMPT_CLEAR, PR_PREEN_OK },
/* Superblock needs_recovery flag is set but not journal is present */
/* 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 */
/* Last mount time is in the future */
{ PR_0_FUTURE_SB_LAST_MOUNT,
- N_("@S last mount time is in the future. "),
+ N_("@S last mount time (%t,\n\tnow = %T) is in the future.\n"),
PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
/* Last write time is in the future */
{ PR_0_FUTURE_SB_LAST_WRITE,
- N_("@S last write time is in the future. "),
+ N_("@S last write time (%t,\n\tnow = %T) is in the future.\n"),
PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
{ PR_0_EXTERNAL_JOURNAL_HINT,
/* group descriptor N checksum is invalid. */
{ PR_0_GDT_CSUM,
- N_("@g descriptor %g checksum is invalid. "),
- PROMPT_FIX, PR_PREEN_OK },
+ N_("@g descriptor %g checksum is %04x, should be %04y. "),
+ PROMPT_FIX, PR_LATCH_BG_CHECKSUM },
/* group descriptor N marked uninitialized without feature set. */
{ PR_0_GDT_UNINIT,
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_("The test_fs flag is set (and ext4 is available). "),
PROMPT_CLEAR, PR_PREEN_OK },
+ /* 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 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 the hardware clock being incorrectly set). "),
+ PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
+
+ /* Block group checksum (latch question) is invalid. */
+ { PR_0_GDT_CSUM_LATCH,
+ 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 },
+
+ /*
+ * metadata_csum implies uninit_bg; both feature bits cannot
+ * be set simultaneously.
+ */
+ { PR_0_META_AND_GDT_CSUM_SET,
+ N_("@S metadata_csum supersedes uninit_bg; both feature "
+ "bits cannot be set simultaneously."),
+ PROMPT_FIX, PR_PREEN_OK | PR_NO_OK},
+
+ /* Superblock has invalid MMP checksum. */
+ { PR_0_MMP_CSUM_INVALID,
+ N_("@S MMP block checksum does not match MMP block. "),
+ PROMPT_FIX, PR_PREEN_OK | PR_NO_OK},
+
+ /* 64bit is set but extents is unset. */
+ { PR_0_64BIT_WITHOUT_EXTENTS,
+ N_("@S 64bit filesystems needs extents to access the whole disk. "),
+ PROMPT_FIX, PR_PREEN_OK | PR_NO_OK},
+
+ /* The first_meta_bg is too big */
+ { PR_0_FIRST_META_BG_TOO_BIG,
+ N_("First_meta_bg is too big. (%N, max value %g). "),
+ PROMPT_CLEAR, 0 },
+
+ /* External journal has corrupt superblock */
+ { PR_0_EXT_JOURNAL_SUPER_CSUM_INVALID,
+ N_("External @j @S checksum does not match @S. "),
+ PROMPT_FIX, PR_PREEN_OK },
+
/* Pass 1 errors */
/* Pass 1: Checking inodes, blocks, and sizes */
N_("Pass 1: Checking @is, @bs, and sizes\n"),
PROMPT_NONE, 0 },
- /* Root directory is not an inode */
+ /* Root inode is not a directory */
{ PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
PROMPT_CLEAR, 0 },
- /* Root directory has dtime set */
+ /* Root inode has dtime set */
{ PR_1_ROOT_DTIME,
N_("@r has dtime set (probably due to old mke2fs). "),
PROMPT_FIX, PR_PREEN_OK },
/* 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) */
/* 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) */
/* 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,
PROMPT_CLEAR, 0},
/* Error allocating EA region allocation structure */
- { PR_1_EA_ALLOC_REGION,
- N_("@A @a @b %b. "),
- PROMPT_ABORT, 0},
+ { PR_1_EA_ALLOC_REGION_ABORT,
+ N_("@A @a region allocation structure. "),
+ PROMPT_NONE, PR_FATAL},
/* Error EA allocation collision */
{ PR_1_EA_ALLOC_COLLISION,
/* 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 */
/* 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 },
+
+ /* inode seems to contain garbage */
+ { PR_1_INODE_IS_GARBAGE,
+ N_("@i %i seems to contain garbage. "),
+ PROMPT_CLEAR, 0 },
+
+ /* inode passes checks, but checksum does not match inode */
+ { PR_1_INODE_ONLY_CSUM_INVALID,
+ N_("@i %i passes checks, but checksum does not match @i. "),
+ PROMPT_FIX, PR_PREEN_OK },
+
+ /* Inode extended attribute is corrupt (allocation collision) */
+ { PR_1_INODE_EA_ALLOC_COLLISION,
+ N_("@i %i @a is corrupt (allocation collision). "),
+ PROMPT_CLEAR, 0},
+
+ /*
+ * Inode extent block passes checks, but checksum does not match
+ * extent
+ */
+ { PR_1_EXTENT_ONLY_CSUM_INVALID,
+ N_("@i %i extent block passes checks, but checksum does not match "
+ "extent\n\t(logical @b %c, @n physical @b %b, len %N)\n"),
+ PROMPT_FIX, 0 },
+
+ /*
+ * Inode extended attribute block passes checks, but checksum does not
+ * match block.
+ */
+ { PR_1_EA_BLOCK_ONLY_CSUM_INVALID,
+ N_("@i %i @a @b %b passes checks, but checksum does not match @b. "),
+ PROMPT_FIX, 0 },
+
+ /*
+ * Interior extent node logical offset doesn't match first node below it
+ */
+ { PR_1_EXTENT_INDEX_START_INVALID,
+ N_("Interior @x node level %N of @i %i:\n"
+ "Logical start %b does not match logical start %c at next level. "),
+ PROMPT_FIX, 0 },
+
+ /* Extent end is out of bounds for the tree */
+ { PR_1_EXTENT_END_OUT_OF_BOUNDS,
+ N_("@i %i, end of extent exceeds allowed value\n\t(logical @b %c, physical @b %b, len %N)\n"),
+ PROMPT_CLEAR, 0 },
+
+ /* Inode has inline data, but superblock is missing INLINE_DATA feature. */
+ { PR_1_INLINE_DATA_FEATURE,
+ N_("@i %i has inline data, but @S is missing INLINE_DATA feature\n"),
+ PROMPT_CLEAR, PR_PREEN_OK },
+
+ /* INLINE_DATA feature is set in a non-inline-data filesystem */
+ { PR_1_INLINE_DATA_SET,
+ N_("@i %i has INLINE_DATA_FL flag on @f without inline data support.\n"),
+ PROMPT_CLEAR, 0 },
+
+ /*
+ * Inode block conflicts with critical metadata, skipping
+ * block checks
+ */
+ { PR_1_CRITICAL_METADATA_COLLISION,
+ N_("@i %i block %b conflicts with critical metadata, skipping block checks.\n"),
+ PROMPT_NONE, 0 },
+
+ /* Directory inode block <block> should be at block <otherblock> */
+ { PR_1_COLLAPSE_DBLOCK,
+ N_("@d @i %i @b %b should be at @b %c. "),
+ PROMPT_FIX, 0 },
+
+ /* Extents/inlinedata flag set on a device or socket inode */
+ { PR_1_UNINIT_DBLOCK,
+ N_("@d @i %i has @x marked uninitialized at @b %c. "),
+ PROMPT_FIX, PR_PREEN_OK },
+
+ /* Inode logical block (physical block ) is misaligned. */
+ { PR_1_MISALIGNED_CLUSTER,
+ N_("@i %i logical @b %b (physical @b %c) violates cluster allocation rules.\nWill fix in pass 1B.\n"),
+ PROMPT_NONE, 0 },
+
+ /* Inode has INLINE_DATA_FL flag but extended attribute not found */
+ { PR_1_INLINE_DATA_NO_ATTR,
+ N_("@i %i has INLINE_DATA_FL flag but @a not found. "),
+ PROMPT_TRUNCATE, 0 },
+
+ /* Extents/inlinedata flag set on a device or socket inode */
+ { PR_1_SPECIAL_EXTENTS_IDATA,
+ N_("Special (@v/socket/fifo) file (@i %i) has extents\n"
+ "or inline-data flag set. "),
+ PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
+
+ /* Inode has extent header but inline data flag is set */
+ { PR_1_CLEAR_INLINE_DATA_FOR_EXTENT,
+ N_("@i %i has @x header but inline data flag is set.\n"),
+ PROMPT_FIX, 0 },
+
+ /* Inode seems to have inline data but extent flag is set */
+ { PR_1_CLEAR_EXTENT_FOR_INLINE_DATA,
+ N_("@i %i seems to have inline data but @x flag is set.\n"),
+ PROMPT_FIX, 0 },
+
+ /* Inode seems to have block map but inline data and extent flags set */
+ { PR_1_CLEAR_EXTENT_INLINE_DATA_FLAGS,
+ N_("@i %i seems to have @b map but inline data and @x flags set.\n"),
+ PROMPT_FIX, 0 },
+
+ /* Inode has inline data and extent flags but i_block contains junk */
+ { PR_1_CLEAR_EXTENT_INLINE_DATA_INODE,
+ N_("@i %i has inline data and @x flags set but i_block contains junk.\n"),
+ PROMPT_CLEAR_INODE, 0 },
+
+ /* Bad block list says the bad block list inode is bad */
+ { PR_1_BADBLOCKS_IN_BADBLOCKS,
+ N_("Bad block list says the bad block list @i is bad. "),
+ PROMPT_CLEAR_INODE, 0 },
+
+ /* Error allocating extent region allocation structure */
+ { PR_1_EXTENT_ALLOC_REGION_ABORT,
+ N_("@A @x region allocation structure. "),
+ PROMPT_NONE, PR_FATAL},
+
+ /* Inode has a duplicate extent mapping */
+ { PR_1_EXTENT_COLLISION,
+ N_("@i %i has a duplicate @x mapping\n\t(logical @b %c, @n physical @b %b, len %N)\n"),
+ PROMPT_CLEAR, 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 },
+ /* Duplicate/bad block range in inode */
+ { PR_1B_DUP_RANGE,
+ " %b--%c",
+ PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
/* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
{ PR_1C_PASS_HEADER,
/* 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 */
N_("@n @i number for '.' in @d @i %i.\n"),
PROMPT_FIX, 0 },
- /* Directory entry has bad inode number */
+ /* Entry 'xxxx' in /a/b/c has bad inode number.*/
{ PR_2_BAD_INO,
N_("@E has @n @i #: %Di.\n"),
PROMPT_CLEAR, 0 },
- /* Directory entry has deleted or unused inode */
+ /* Entry 'xxxx' in /a/b/c has deleted/unused inode nnnnn.*/
{ PR_2_UNUSED_INODE,
N_("@E has @D/unused @i %Di. "),
PROMPT_CLEAR, PR_PREEN_OK },
/* 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 */
/* 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 */
/* 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 */
/* i_blocks_hi should be zero */
{ PR_2_I_FILE_ACL_HI_ZERO,
N_("i_file_acl_hi @F %N, @s zero.\n"),
- PROMPT_CLEAR, 0 },
+ PROMPT_CLEAR, PR_PREEN_OK },
+
+ /* htree root node fails checksum */
+ { PR_2_HTREE_ROOT_CSUM_INVALID,
+ N_("@p @h %d: root node fails checksum.\n"),
+ PROMPT_CLEAR_HTREE, PR_PREEN_OK },
+
+ /* htree internal node fails checksum */
+ { PR_2_HTREE_NODE_CSUM_INVALID,
+ N_("@p @h %d: internal node fails checksum.\n"),
+ PROMPT_CLEAR_HTREE, PR_PREEN_OK },
+
+ /* leaf node has no checksum */
+ { PR_2_LEAF_NODE_MISSING_CSUM,
+ N_("@d @i %i, %B, offset %N: @d has no checksum.\n"),
+ PROMPT_FIX, PR_PREEN_OK },
+
+ /* leaf node passes checks but fails checksum */
+ { PR_2_LEAF_NODE_ONLY_CSUM_INVALID,
+ N_("@d @i %i, %B, offset %N: @d passes checks but fails checksum.\n"),
+ PROMPT_FIX, PR_PREEN_OK },
+
+ /* inline directory inode size must be a multiple of 4 */
+ { PR_2_BAD_INLINE_DIR_SIZE,
+ N_("Inline @d @i %i size (%N) must be a multiple of 4.\n"),
+ PROMPT_FIX, 0 },
+
+ /* fixing size of inline directory inode failed */
+ { PR_2_FIX_INLINE_DIR_FAILED,
+ N_("Fixing size of inline @d @i %i failed.\n"),
+ PROMPT_TRUNCATE, 0 },
/* Pass 3 errors */
N_("/@l is not a @d (ino=%i)\n"),
PROMPT_UNLINK, 0 },
+ /* Lost+found has inline data */
+ { PR_3_LPF_INLINE_DATA,
+ N_("/@l has inline data\n"),
+ PROMPT_CLEAR, 0 },
+
+ /* Cannot allocate /lost+found. */
+ { PR_3_LPF_NO_SPACE,
+ N_("Cannot allocate space for /@l.\nPlace lost files in root directory instead"),
+ PROMPT_NULL, 0 },
+
+ /* Delete some files and re-run e2fsck. */
+ { PR_3_NO_SPACE_TO_RECOVER,
+ N_("Insufficient space to recover lost files!\nMove data off the @f and re-run e2fsck.\n\n"),
+ PROMPT_NONE, 0 },
+
/* Pass 3A Directory Optimization */
/* Pass 3A: Optimizing directories */
/* 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 },
+ /* Group N inode bitmap does not match checksum */
+ { PR_5_INODE_BITMAP_CSUM_INVALID,
+ N_("@g %g @i @B does not match checksum.\n"),
+ PROMPT_FIX, PR_LATCH_IBITMAP | PR_PREEN_OK },
+
+ /* Group N block bitmap does not match checksum */
+ { PR_5_BLOCK_BITMAP_CSUM_INVALID,
+ N_("@g %g @b @B does not match checksum.\n"),
+ PROMPT_FIX, PR_LATCH_BBITMAP | PR_PREEN_OK },
+
/* 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 },
+
+ /* Error setting block group checksum info */
+ { PR_6_SET_BG_CHECKSUM,
+ N_("Error setting @b @g checksum info: %m\n"),
+ PROMPT_NULL, PR_FATAL },
+
+ /* Error writing file system info */
+ { PR_6_FLUSH_FILESYSTEM,
+ N_("Error writing file system info: %m\n"),
+ PROMPT_NULL, PR_FATAL },
+
+ /* Error flushing writes to storage device */
+ { PR_6_IO_FLUSH,
+ N_("Error flushing writes to storage device: %m\n"),
+ PROMPT_NULL, PR_FATAL },
+
{ 0 }
};
{ PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
{ PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
{ PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
+ { PR_LATCH_BG_CHECKSUM, PR_0_GDT_CSUM_LATCH, 0 },
{ -1, 0, 0 },
};
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;
return 0;
}
if (!(ptr->flags & PR_CONFIG)) {
- char key[9], *new_desc;
+ char key[9], *new_desc = NULL;
sprintf(key, "0x%06x", code);
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)
if (ptr->flags & PR_AFTER_CODE)
answer = fix_problem(ctx, ptr->second_code, pctx);
+ if (answer && (ptr->prompt != PROMPT_NONE))
+ ctx->flags |= E2F_FLAG_PROBLEMS_FIXED;
+
return 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");