Home | History | Annotate | Download | only in e2fsck
      1 /*
      2  * problem.c --- report filesystem problems to the user
      3  *
      4  * Copyright 1996, 1997 by Theodore Ts'o
      5  *
      6  * %Begin-Header%
      7  * This file may be redistributed under the terms of the GNU Public
      8  * License.
      9  * %End-Header%
     10  */
     11 
     12 #include <stdlib.h>
     13 #include <unistd.h>
     14 #include <string.h>
     15 #include <ctype.h>
     16 #include <termios.h>
     17 
     18 #include "e2fsck.h"
     19 
     20 #include "problem.h"
     21 #include "problemP.h"
     22 
     23 #define PROMPT_NONE	0
     24 #define PROMPT_FIX	1
     25 #define PROMPT_CLEAR	2
     26 #define PROMPT_RELOCATE	3
     27 #define PROMPT_ALLOCATE 4
     28 #define PROMPT_EXPAND	5
     29 #define PROMPT_CONNECT	6
     30 #define PROMPT_CREATE	7
     31 #define PROMPT_SALVAGE	8
     32 #define PROMPT_TRUNCATE	9
     33 #define PROMPT_CLEAR_INODE 10
     34 #define PROMPT_ABORT	11
     35 #define PROMPT_SPLIT	12
     36 #define PROMPT_CONTINUE	13
     37 #define PROMPT_CLONE	14
     38 #define PROMPT_DELETE	15
     39 #define PROMPT_SUPPRESS 16
     40 #define PROMPT_UNLINK	17
     41 #define PROMPT_CLEAR_HTREE 18
     42 #define PROMPT_RECREATE 19
     43 #define PROMPT_NULL	20
     44 
     45 /*
     46  * These are the prompts which are used to ask the user if they want
     47  * to fix a problem.
     48  */
     49 static const char *prompt[] = {
     50 	N_("(no prompt)"),	/* 0 */
     51 	N_("Fix"),		/* 1 */
     52 	N_("Clear"),		/* 2 */
     53 	N_("Relocate"),		/* 3 */
     54 	N_("Allocate"),		/* 4 */
     55 	N_("Expand"),		/* 5 */
     56 	N_("Connect to /lost+found"), /* 6 */
     57 	N_("Create"),		/* 7 */
     58 	N_("Salvage"),		/* 8 */
     59 	N_("Truncate"),		/* 9 */
     60 	N_("Clear inode"),	/* 10 */
     61 	N_("Abort"),		/* 11 */
     62 	N_("Split"),		/* 12 */
     63 	N_("Continue"),		/* 13 */
     64 	N_("Clone multiply-claimed blocks"), /* 14 */
     65 	N_("Delete file"),	/* 15 */
     66 	N_("Suppress messages"),/* 16 */
     67 	N_("Unlink"),		/* 17 */
     68 	N_("Clear HTree index"),/* 18 */
     69 	N_("Recreate"),		/* 19 */
     70 	"",			/* 20 */
     71 };
     72 
     73 /*
     74  * These messages are printed when we are preen mode and we will be
     75  * automatically fixing the problem.
     76  */
     77 static const char *preen_msg[] = {
     78 	N_("(NONE)"),		/* 0 */
     79 	N_("FIXED"),		/* 1 */
     80 	N_("CLEARED"),		/* 2 */
     81 	N_("RELOCATED"),	/* 3 */
     82 	N_("ALLOCATED"),	/* 4 */
     83 	N_("EXPANDED"),		/* 5 */
     84 	N_("RECONNECTED"),	/* 6 */
     85 	N_("CREATED"),		/* 7 */
     86 	N_("SALVAGED"),		/* 8 */
     87 	N_("TRUNCATED"),	/* 9 */
     88 	N_("INODE CLEARED"),	/* 10 */
     89 	N_("ABORTED"),		/* 11 */
     90 	N_("SPLIT"),		/* 12 */
     91 	N_("CONTINUING"),	/* 13 */
     92 	N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
     93 	N_("FILE DELETED"),	/* 15 */
     94 	N_("SUPPRESSED"),	/* 16 */
     95 	N_("UNLINKED"),		/* 17 */
     96 	N_("HTREE INDEX CLEARED"),/* 18 */
     97 	N_("WILL RECREATE"),	/* 19 */
     98 	"",			/* 20 */
     99 };
    100 
    101 static struct e2fsck_problem problem_table[] = {
    102 
    103 	/* Pre-Pass 1 errors */
    104 
    105 	/* Block bitmap not in group */
    106 	{ PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g.  (@b %b)\n"),
    107 	  PROMPT_RELOCATE, PR_LATCH_RELOC },
    108 
    109 	/* Inode bitmap not in group */
    110 	{ PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g.  (@b %b)\n"),
    111 	  PROMPT_RELOCATE, PR_LATCH_RELOC },
    112 
    113 	/* Inode table not in group */
    114 	{ PR_0_ITABLE_NOT_GROUP,
    115 	  N_("@i table for @g %g is not in @g.  (@b %b)\n"
    116 	  "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
    117 	  PROMPT_RELOCATE, PR_LATCH_RELOC },
    118 
    119 	/* Superblock corrupt */
    120 	{ PR_0_SB_CORRUPT,
    121 	  N_("\nThe @S could not be read or does not describe a correct ext2\n"
    122 	  "@f.  If the @v is valid and it really contains an ext2\n"
    123 	  "@f (and not swap or ufs or something else), then the @S\n"
    124 	  "is corrupt, and you might try running e2fsck with an alternate @S:\n"
    125 	  "    e2fsck -b %S <@v>\n\n"),
    126 	  PROMPT_NONE, PR_FATAL },
    127 
    128 	/* Filesystem size is wrong */
    129 	{ PR_0_FS_SIZE_WRONG,
    130 	  N_("The @f size (according to the @S) is %b @bs\n"
    131 	  "The physical size of the @v is %c @bs\n"
    132 	  "Either the @S or the partition table is likely to be corrupt!\n"),
    133 	  PROMPT_ABORT, 0 },
    134 
    135 	/* Fragments not supported */
    136 	{ PR_0_NO_FRAGMENTS,
    137 	  N_("@S @b_size = %b, fragsize = %c.\n"
    138 	  "This version of e2fsck does not support fragment sizes different\n"
    139 	  "from the @b size.\n"),
    140 	  PROMPT_NONE, PR_FATAL },
    141 
    142 	  /* Bad blocks_per_group */
    143 	{ PR_0_BLOCKS_PER_GROUP,
    144 	  N_("@S @bs_per_group = %b, should have been %c\n"),
    145 	  PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
    146 
    147 	/* Bad first_data_block */
    148 	{ PR_0_FIRST_DATA_BLOCK,
    149 	  N_("@S first_data_@b = %b, should have been %c\n"),
    150 	  PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
    151 
    152 	/* Adding UUID to filesystem */
    153 	{ PR_0_ADD_UUID,
    154 	  N_("@f did not have a UUID; generating one.\n\n"),
    155 	  PROMPT_NONE, 0 },
    156 
    157 	/* Relocate hint */
    158 	{ PR_0_RELOCATE_HINT,
    159 	  N_("Note: if several inode or block bitmap blocks or part\n"
    160 	  "of the inode table require relocation, you may wish to try\n"
    161 	  "running e2fsck with the '-b %S' option first.  The problem\n"
    162 	  "may lie only with the primary block group descriptors, and\n"
    163 	  "the backup block group descriptors may be OK.\n\n"),
    164 	  PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
    165 
    166 	/* Miscellaneous superblock corruption */
    167 	{ PR_0_MISC_CORRUPT_SUPER,
    168 	  N_("Corruption found in @S.  (%s = %N).\n"),
    169 	  PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
    170 
    171 	/* Error determing physical device size of filesystem */
    172 	{ PR_0_GETSIZE_ERROR,
    173 	  N_("Error determining size of the physical @v: %m\n"),
    174 	  PROMPT_NONE, PR_FATAL },
    175 
    176 	/* Inode count in superblock is incorrect */
    177 	{ PR_0_INODE_COUNT_WRONG,
    178 	  N_("@i count in @S is %i, @s %j.\n"),
    179 	  PROMPT_FIX, 0 },
    180 
    181 	{ PR_0_HURD_CLEAR_FILETYPE,
    182 	  N_("The Hurd does not support the filetype feature.\n"),
    183 	  PROMPT_CLEAR, 0 },
    184 
    185 	/* Journal inode is invalid */
    186 	{ PR_0_JOURNAL_BAD_INODE,
    187 	  N_("@S has an @n @j (@i %i).\n"),
    188 	  PROMPT_CLEAR, PR_PREEN_OK },
    189 
    190 	/* The external journal has (unsupported) multiple filesystems */
    191 	{ PR_0_JOURNAL_UNSUPP_MULTIFS,
    192 	  N_("External @j has multiple @f users (unsupported).\n"),
    193 	  PROMPT_NONE, PR_FATAL },
    194 
    195 	/* Can't find external journal */
    196 	{ PR_0_CANT_FIND_JOURNAL,
    197 	  N_("Can't find external @j\n"),
    198 	  PROMPT_NONE, PR_FATAL },
    199 
    200 	/* External journal has bad superblock */
    201 	{ PR_0_EXT_JOURNAL_BAD_SUPER,
    202 	  N_("External @j has bad @S\n"),
    203 	  PROMPT_NONE, PR_FATAL },
    204 
    205 	/* Superblock has a bad journal UUID */
    206 	{ PR_0_JOURNAL_BAD_UUID,
    207 	  N_("External @j does not support this @f\n"),
    208 	  PROMPT_NONE, PR_FATAL },
    209 
    210 	/* Journal has an unknown superblock type */
    211 	{ PR_0_JOURNAL_UNSUPP_SUPER,
    212 	  N_("@f @j @S is unknown type %N (unsupported).\n"
    213 	     "It is likely that your copy of e2fsck is old and/or doesn't "
    214 	     "support this @j format.\n"
    215 	     "It is also possible the @j @S is corrupt.\n"),
    216 	  PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
    217 
    218 	/* Journal superblock is corrupt */
    219 	{ PR_0_JOURNAL_BAD_SUPER,
    220 	  N_("@j @S is corrupt.\n"),
    221 	  PROMPT_FIX, PR_PREEN_OK },
    222 
    223 	/* Superblock has_journal flag is clear but has a journal */
    224 	{ PR_0_JOURNAL_HAS_JOURNAL,
    225 	  N_("@S has_@j flag is clear, but a @j %s is present.\n"),
    226 	  PROMPT_CLEAR, PR_PREEN_OK },
    227 
    228 	/* Superblock needs_recovery flag is set but not journal is present */
    229 	{ PR_0_JOURNAL_RECOVER_SET,
    230 	  N_("@S needs_recovery flag is set, but no @j is present.\n"),
    231 	  PROMPT_CLEAR, PR_PREEN_OK },
    232 
    233 	/* Superblock needs_recovery flag is set, but journal has data */
    234 	{ PR_0_JOURNAL_RECOVERY_CLEAR,
    235 	  N_("@S needs_recovery flag is clear, but @j has data.\n"),
    236 	  PROMPT_NONE, 0 },
    237 
    238 	/* Ask if we should clear the journal */
    239 	{ PR_0_JOURNAL_RESET_JOURNAL,
    240 	  N_("Clear @j"),
    241 	  PROMPT_NULL, PR_PREEN_NOMSG },
    242 
    243 	/* Filesystem revision is 0, but feature flags are set */
    244 	{ PR_0_FS_REV_LEVEL,
    245 	  N_("@f has feature flag(s) set, but is a revision 0 @f.  "),
    246 	  PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
    247 
    248 	/* Clearing orphan inode */
    249 	{ PR_0_ORPHAN_CLEAR_INODE,
    250 	  N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
    251 	  PROMPT_NONE, 0 },
    252 
    253 	/* Illegal block found in orphaned inode */
    254 	{ PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
    255 	   N_("@I %B (%b) found in @o @i %i.\n"),
    256 	  PROMPT_NONE, 0 },
    257 
    258 	/* Already cleared block found in orphaned inode */
    259 	{ PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
    260 	   N_("Already cleared %B (%b) found in @o @i %i.\n"),
    261 	  PROMPT_NONE, 0 },
    262 
    263 	/* Illegal orphan inode in superblock */
    264 	{ PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
    265 	  N_("@I @o @i %i in @S.\n"),
    266 	  PROMPT_NONE, 0 },
    267 
    268 	/* Illegal inode in orphaned inode list */
    269 	{ PR_0_ORPHAN_ILLEGAL_INODE,
    270 	  N_("@I @i %i in @o @i list.\n"),
    271 	  PROMPT_NONE, 0 },
    272 
    273 	/* Journal superblock has an unknown read-only feature flag set */
    274 	{ PR_0_JOURNAL_UNSUPP_ROCOMPAT,
    275 	  N_("@j @S has an unknown read-only feature flag set.\n"),
    276 	  PROMPT_ABORT, 0 },
    277 
    278 	/* Journal superblock has an unknown incompatible feature flag set */
    279 	{ PR_0_JOURNAL_UNSUPP_INCOMPAT,
    280 	  N_("@j @S has an unknown incompatible feature flag set.\n"),
    281 	  PROMPT_ABORT, 0 },
    282 
    283 	/* Journal has unsupported version number */
    284 	{ PR_0_JOURNAL_UNSUPP_VERSION,
    285 	  N_("@j version not supported by this e2fsck.\n"),
    286 	  PROMPT_ABORT, 0 },
    287 
    288 	/* Moving journal to hidden file */
    289 	{ PR_0_MOVE_JOURNAL,
    290 	  N_("Moving @j from /%s to hidden @i.\n\n"),
    291 	  PROMPT_NONE, 0 },
    292 
    293 	/* Error moving journal to hidden file */
    294 	{ PR_0_ERR_MOVE_JOURNAL,
    295 	  N_("Error moving @j: %m\n\n"),
    296 	  PROMPT_NONE, 0 },
    297 
    298 	/* Clearing V2 journal superblock */
    299 	{ PR_0_CLEAR_V2_JOURNAL,
    300 	  N_("Found @n V2 @j @S fields (from V1 @j).\n"
    301 	     "Clearing fields beyond the V1 @j @S...\n\n"),
    302 	  PROMPT_NONE, 0 },
    303 
    304 	/* Ask if we should run the journal anyway */
    305 	{ PR_0_JOURNAL_RUN,
    306 	  N_("Run @j anyway"),
    307 	  PROMPT_NULL, 0 },
    308 
    309 	/* Run the journal by default */
    310 	{ PR_0_JOURNAL_RUN_DEFAULT,
    311 	  N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
    312 	  PROMPT_NONE, 0 },
    313 
    314 	/* Backup journal inode blocks */
    315 	{ PR_0_BACKUP_JNL,
    316 	  N_("Backing up @j @i @b information.\n\n"),
    317 	  PROMPT_NONE, 0 },
    318 
    319 	/* Reserved blocks w/o resize_inode */
    320 	{ PR_0_NONZERO_RESERVED_GDT_BLOCKS,
    321 	  N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
    322 	     "is %N; @s zero.  "),
    323 	  PROMPT_FIX, 0 },
    324 
    325 	/* Resize_inode not enabled, but resize inode is non-zero */
    326 	{ PR_0_CLEAR_RESIZE_INODE,
    327 	  N_("Resize_@i not enabled, but the resize @i is non-zero.  "),
    328 	  PROMPT_CLEAR, 0 },
    329 
    330 	/* Resize inode invalid */
    331 	{ PR_0_RESIZE_INODE_INVALID,
    332 	  N_("Resize @i not valid.  "),
    333 	  PROMPT_RECREATE, 0 },
    334 
    335 	/* Last mount time is in the future */
    336 	{ PR_0_FUTURE_SB_LAST_MOUNT,
    337 	  N_("@S last mount time (%t,\n\tnow = %T) is in the future.\n"),
    338 	  PROMPT_FIX, PR_NO_OK },
    339 
    340 	/* Last write time is in the future */
    341 	{ PR_0_FUTURE_SB_LAST_WRITE,
    342 	  N_("@S last write time (%t,\n\tnow = %T) is in the future.\n"),
    343 	  PROMPT_FIX, PR_NO_OK },
    344 
    345 	{ PR_0_EXTERNAL_JOURNAL_HINT,
    346 	  N_("@S hint for external superblock @s %X.  "),
    347 	     PROMPT_FIX, PR_PREEN_OK },
    348 
    349 	/* Adding dirhash hint */
    350 	{ PR_0_DIRHASH_HINT,
    351 	  N_("Adding dirhash hint to @f.\n\n"),
    352 	  PROMPT_NONE, 0 },
    353 
    354 	/* group descriptor N checksum is invalid. */
    355 	{ PR_0_GDT_CSUM,
    356 	  N_("@g descriptor %g checksum is invalid.  "),
    357 	     PROMPT_FIX, PR_LATCH_BG_CHECKSUM },
    358 
    359 	/* group descriptor N marked uninitialized without feature set. */
    360 	{ PR_0_GDT_UNINIT,
    361 	  N_("@g descriptor %g marked uninitialized without feature set.\n"),
    362 	     PROMPT_FIX, PR_PREEN_OK },
    363 
    364 	/* group N block bitmap uninitialized but inode bitmap in use. */
    365 	{ PR_0_BB_UNINIT_IB_INIT,
    366 	  N_("@g %g @b @B uninitialized but @i @B in use.\n"),
    367 	     PROMPT_FIX, PR_PREEN_OK },
    368 
    369 	/* Group descriptor N has invalid unused inodes count. */
    370 	{ PR_0_GDT_ITABLE_UNUSED,
    371 	  N_("@g descriptor %g has invalid unused inodes count %b.  "),
    372 	     PROMPT_FIX, PR_PREEN_OK },
    373 
    374 	/* Last group block bitmap uninitialized. */
    375 	{ PR_0_BB_UNINIT_LAST,
    376 	  N_("Last @g @b @B uninitialized.  "),
    377 	     PROMPT_FIX, PR_PREEN_OK },
    378 
    379 	/* Journal transaction found corrupt */
    380 	{ PR_0_JNL_TXN_CORRUPT,
    381 	  N_("Journal transaction %i was corrupt, replay was aborted.\n"),
    382 	  PROMPT_NONE, 0 },
    383 
    384 	{ PR_0_CLEAR_TESTFS_FLAG,
    385 	  N_("The test_fs flag is set (and ext4 is available).  "),
    386 	  PROMPT_CLEAR, PR_PREEN_OK },
    387 
    388 	/* Last mount time is in the future (fudged) */
    389 	{ PR_0_FUTURE_SB_LAST_MOUNT_FUDGED,
    390 	  N_("@S last mount time is in the future.\n\t(by less than a day, "
    391 	     "probably due to the hardware clock being incorrectly set)  "),
    392 	  PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
    393 
    394 	/* Last write time is in the future (fudged) */
    395 	{ PR_0_FUTURE_SB_LAST_WRITE_FUDGED,
    396 	  N_("@S last write time is in the future.\n\t(by less than a day, "
    397 	     "probably due to the hardware clock being incorrectly set).  "),
    398 	  PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
    399 
    400 	/* Block group checksum (latch question) is invalid. */
    401 	{ PR_0_GDT_CSUM_LATCH,
    402 	  N_("One or more @b @g descriptor checksums are invalid.  "),
    403 	     PROMPT_FIX, PR_PREEN_OK },
    404 
    405 	/* Pass 1 errors */
    406 
    407 	/* Pass 1: Checking inodes, blocks, and sizes */
    408 	{ PR_1_PASS_HEADER,
    409 	  N_("Pass 1: Checking @is, @bs, and sizes\n"),
    410 	  PROMPT_NONE, 0 },
    411 
    412 	/* Root directory is not an inode */
    413 	{ PR_1_ROOT_NO_DIR, N_("@r is not a @d.  "),
    414 	  PROMPT_CLEAR, 0 },
    415 
    416 	/* Root directory has dtime set */
    417 	{ PR_1_ROOT_DTIME,
    418 	  N_("@r has dtime set (probably due to old mke2fs).  "),
    419 	  PROMPT_FIX, PR_PREEN_OK },
    420 
    421 	/* Reserved inode has bad mode */
    422 	{ PR_1_RESERVED_BAD_MODE,
    423 	  N_("Reserved @i %i (%Q) has @n mode.  "),
    424 	  PROMPT_CLEAR, PR_PREEN_OK },
    425 
    426 	/* Deleted inode has zero dtime */
    427 	{ PR_1_ZERO_DTIME,
    428 	  N_("@D @i %i has zero dtime.  "),
    429 	  PROMPT_FIX, PR_PREEN_OK },
    430 
    431 	/* Inode in use, but dtime set */
    432 	{ PR_1_SET_DTIME,
    433 	  N_("@i %i is in use, but has dtime set.  "),
    434 	  PROMPT_FIX, PR_PREEN_OK },
    435 
    436 	/* Zero-length directory */
    437 	{ PR_1_ZERO_LENGTH_DIR,
    438 	  N_("@i %i is a @z @d.  "),
    439 	  PROMPT_CLEAR, PR_PREEN_OK },
    440 
    441 	/* Block bitmap conflicts with some other fs block */
    442 	{ PR_1_BB_CONFLICT,
    443 	  N_("@g %g's @b @B at %b @C.\n"),
    444 	  PROMPT_RELOCATE, 0 },
    445 
    446 	/* Inode bitmap conflicts with some other fs block */
    447 	{ PR_1_IB_CONFLICT,
    448 	  N_("@g %g's @i @B at %b @C.\n"),
    449 	  PROMPT_RELOCATE, 0 },
    450 
    451 	/* Inode table conflicts with some other fs block */
    452 	{ PR_1_ITABLE_CONFLICT,
    453 	  N_("@g %g's @i table at %b @C.\n"),
    454 	  PROMPT_RELOCATE, 0 },
    455 
    456 	/* Block bitmap is on a bad block */
    457 	{ PR_1_BB_BAD_BLOCK,
    458 	  N_("@g %g's @b @B (%b) is bad.  "),
    459 	  PROMPT_RELOCATE, 0 },
    460 
    461 	/* Inode bitmap is on a bad block */
    462 	{ PR_1_IB_BAD_BLOCK,
    463 	  N_("@g %g's @i @B (%b) is bad.  "),
    464 	  PROMPT_RELOCATE, 0 },
    465 
    466 	/* Inode has incorrect i_size */
    467 	{ PR_1_BAD_I_SIZE,
    468 	  N_("@i %i, i_size is %Is, @s %N.  "),
    469 	  PROMPT_FIX, PR_PREEN_OK },
    470 
    471 	/* Inode has incorrect i_blocks */
    472 	{ PR_1_BAD_I_BLOCKS,
    473 	  N_("@i %i, i_@bs is %Ib, @s %N.  "),
    474 	  PROMPT_FIX, PR_PREEN_OK },
    475 
    476 	/* Illegal blocknumber in inode */
    477 	{ PR_1_ILLEGAL_BLOCK_NUM,
    478 	  N_("@I %B (%b) in @i %i.  "),
    479 	  PROMPT_CLEAR, PR_LATCH_BLOCK },
    480 
    481 	/* Block number overlaps fs metadata */
    482 	{ PR_1_BLOCK_OVERLAPS_METADATA,
    483 	  N_("%B (%b) overlaps @f metadata in @i %i.  "),
    484 	  PROMPT_CLEAR, PR_LATCH_BLOCK },
    485 
    486 	/* Inode has illegal blocks (latch question) */
    487 	{ PR_1_INODE_BLOCK_LATCH,
    488 	  N_("@i %i has illegal @b(s).  "),
    489 	  PROMPT_CLEAR, 0 },
    490 
    491 	/* Too many bad blocks in inode */
    492 	{ PR_1_TOO_MANY_BAD_BLOCKS,
    493 	  N_("Too many illegal @bs in @i %i.\n"),
    494 	  PROMPT_CLEAR_INODE, PR_NO_OK },
    495 
    496 	/* Illegal block number in bad block inode */
    497 	{ PR_1_BB_ILLEGAL_BLOCK_NUM,
    498 	  N_("@I %B (%b) in bad @b @i.  "),
    499 	  PROMPT_CLEAR, PR_LATCH_BBLOCK },
    500 
    501 	/* Bad block inode has illegal blocks (latch question) */
    502 	{ PR_1_INODE_BBLOCK_LATCH,
    503 	  N_("Bad @b @i has illegal @b(s).  "),
    504 	  PROMPT_CLEAR, 0 },
    505 
    506 	/* Duplicate or bad blocks in use! */
    507 	{ PR_1_DUP_BLOCKS_PREENSTOP,
    508 	  N_("Duplicate or bad @b in use!\n"),
    509 	  PROMPT_NONE, 0 },
    510 
    511 	/* Bad block used as bad block indirect block */
    512 	{ PR_1_BBINODE_BAD_METABLOCK,
    513 	  N_("Bad @b %b used as bad @b @i indirect @b.  "),
    514 	  PROMPT_CLEAR, PR_LATCH_BBLOCK },
    515 
    516 	/* Inconsistency can't be fixed prompt */
    517 	{ PR_1_BBINODE_BAD_METABLOCK_PROMPT,
    518 	  N_("\nThe bad @b @i has probably been corrupted.  You probably\n"
    519 	     "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
    520 	     "in the @f.\n"),
    521 	  PROMPT_CONTINUE, PR_PREEN_NOMSG },
    522 
    523 	/* Bad primary block */
    524 	{ PR_1_BAD_PRIMARY_BLOCK,
    525 	  N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
    526 	  PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
    527 
    528 	/* Bad primary block prompt */
    529 	{ PR_1_BAD_PRIMARY_BLOCK_PROMPT,
    530 	  N_("You can remove this @b from the bad @b list and hope\n"
    531 	     "that the @b is really OK.  But there are no guarantees.\n\n"),
    532 	  PROMPT_CLEAR, PR_PREEN_NOMSG },
    533 
    534 	/* Bad primary superblock */
    535 	{ PR_1_BAD_PRIMARY_SUPERBLOCK,
    536 	  N_("The primary @S (%b) is on the bad @b list.\n"),
    537 	  PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
    538 
    539 	/* Bad primary block group descriptors */
    540 	{ PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
    541 	  N_("Block %b in the primary @g descriptors "
    542 	  "is on the bad @b list\n"),
    543 	  PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
    544 
    545 	/* Bad superblock in group */
    546 	{ PR_1_BAD_SUPERBLOCK,
    547 	  N_("Warning: Group %g's @S (%b) is bad.\n"),
    548 	  PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
    549 
    550 	/* Bad block group descriptors in group */
    551 	{ PR_1_BAD_GROUP_DESCRIPTORS,
    552 	  N_("Warning: Group %g's copy of the @g descriptors has a bad "
    553 	  "@b (%b).\n"),
    554 	  PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
    555 
    556 	/* Block claimed for no reason */
    557 	{ PR_1_PROGERR_CLAIMED_BLOCK,
    558 	  N_("Programming error?  @b #%b claimed for no reason in "
    559 	  "process_bad_@b.\n"),
    560 	  PROMPT_NONE, PR_PREEN_OK },
    561 
    562 	/* Error allocating blocks for relocating metadata */
    563 	{ PR_1_RELOC_BLOCK_ALLOCATE,
    564 	  N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
    565 	  PROMPT_NONE, PR_PREEN_OK },
    566 
    567 	/* Error allocating block buffer during relocation process */
    568 	{ PR_1_RELOC_MEMORY_ALLOCATE,
    569 	  N_("@A @b buffer for relocating %s\n"),
    570 	  PROMPT_NONE, PR_PREEN_OK },
    571 
    572 	/* Relocating metadata group information from X to Y */
    573 	{ PR_1_RELOC_FROM_TO,
    574 	  N_("Relocating @g %g's %s from %b to %c...\n"),
    575 	  PROMPT_NONE, PR_PREEN_OK },
    576 
    577 	/* Relocating metatdata group information to X */
    578 	{ PR_1_RELOC_TO,
    579 	  N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
    580 	  PROMPT_NONE, PR_PREEN_OK },
    581 
    582 	/* Block read error during relocation process */
    583 	{ PR_1_RELOC_READ_ERR,
    584 	  N_("Warning: could not read @b %b of %s: %m\n"),
    585 	  PROMPT_NONE, PR_PREEN_OK },
    586 
    587 	/* Block write error during relocation process */
    588 	{ PR_1_RELOC_WRITE_ERR,
    589 	  N_("Warning: could not write @b %b for %s: %m\n"),
    590 	  PROMPT_NONE, PR_PREEN_OK },
    591 
    592 	/* Error allocating inode bitmap */
    593 	{ PR_1_ALLOCATE_IBITMAP_ERROR,
    594 	  N_("@A @i @B (%N): %m\n"),
    595 	  PROMPT_NONE, PR_FATAL },
    596 
    597 	/* Error allocating block bitmap */
    598 	{ PR_1_ALLOCATE_BBITMAP_ERROR,
    599 	  N_("@A @b @B (%N): %m\n"),
    600 	  PROMPT_NONE, PR_FATAL },
    601 
    602 	/* Error allocating icount link information */
    603 	{ PR_1_ALLOCATE_ICOUNT,
    604 	  N_("@A icount link information: %m\n"),
    605 	  PROMPT_NONE, PR_FATAL },
    606 
    607 	/* Error allocating directory block array */
    608 	{ PR_1_ALLOCATE_DBCOUNT,
    609 	  N_("@A @d @b array: %m\n"),
    610 	  PROMPT_NONE, PR_FATAL },
    611 
    612 	/* Error while scanning inodes */
    613 	{ PR_1_ISCAN_ERROR,
    614 	  N_("Error while scanning @is (%i): %m\n"),
    615 	  PROMPT_NONE, PR_FATAL },
    616 
    617 	/* Error while iterating over blocks */
    618 	{ PR_1_BLOCK_ITERATE,
    619 	  N_("Error while iterating over @bs in @i %i: %m\n"),
    620 	  PROMPT_NONE, PR_FATAL },
    621 
    622 	/* Error while storing inode count information */
    623 	{ PR_1_ICOUNT_STORE,
    624 	  N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
    625 	  PROMPT_NONE, PR_FATAL },
    626 
    627 	/* Error while storing directory block information */
    628 	{ PR_1_ADD_DBLOCK,
    629 	  N_("Error storing @d @b information "
    630 	  "(@i=%i, @b=%b, num=%N): %m\n"),
    631 	  PROMPT_NONE, PR_FATAL },
    632 
    633 	/* Error while reading inode (for clearing) */
    634 	{ PR_1_READ_INODE,
    635 	  N_("Error reading @i %i: %m\n"),
    636 	  PROMPT_NONE, PR_FATAL },
    637 
    638 	/* Suppress messages prompt */
    639 	{ PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
    640 
    641 	/* Imagic flag set on an inode when filesystem doesn't support it */
    642 	{ PR_1_SET_IMAGIC,
    643 	  N_("@i %i has imagic flag set.  "),
    644 	  PROMPT_CLEAR, 0 },
    645 
    646 	/* Immutable flag set on a device or socket inode */
    647 	{ PR_1_SET_IMMUTABLE,
    648 	  N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
    649 	     "or append-only flag set.  "),
    650 	  PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
    651 
    652 	/* Compression flag set on an inode when filesystem doesn't support it */
    653 	{ PR_1_COMPR_SET,
    654 	  N_("@i %i has @cion flag set on @f without @cion support.  "),
    655 	  PROMPT_CLEAR, 0 },
    656 
    657 	/* Non-zero size for device, fifo or socket inode */
    658 	{ PR_1_SET_NONZSIZE,
    659 	  N_("Special (@v/socket/fifo) @i %i has non-zero size.  "),
    660 	  PROMPT_FIX, PR_PREEN_OK },
    661 
    662 	/* Filesystem revision is 0, but feature flags are set */
    663 	{ PR_1_FS_REV_LEVEL,
    664 	  N_("@f has feature flag(s) set, but is a revision 0 @f.  "),
    665 	  PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
    666 
    667 	/* Journal inode is not in use, but contains data */
    668 	{ PR_1_JOURNAL_INODE_NOT_CLEAR,
    669 	  N_("@j @i is not in use, but contains data.  "),
    670 	  PROMPT_CLEAR, PR_PREEN_OK },
    671 
    672 	/* Journal has bad mode */
    673 	{ PR_1_JOURNAL_BAD_MODE,
    674 	  N_("@j is not regular file.  "),
    675 	  PROMPT_FIX, PR_PREEN_OK },
    676 
    677 	/* Deal with inodes that were part of orphan linked list */
    678 	{ PR_1_LOW_DTIME,
    679 	  N_("@i %i was part of the @o @i list.  "),
    680 	  PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
    681 
    682 	/* Deal with inodes that were part of corrupted orphan linked
    683 	   list (latch question) */
    684 	{ PR_1_ORPHAN_LIST_REFUGEES,
    685 	  N_("@is that were part of a corrupted orphan linked list found.  "),
    686 	  PROMPT_FIX, 0 },
    687 
    688 	/* Error allocating refcount structure */
    689 	{ PR_1_ALLOCATE_REFCOUNT,
    690 	  N_("@A refcount structure (%N): %m\n"),
    691 	  PROMPT_NONE, PR_FATAL },
    692 
    693 	/* Error reading extended attribute block */
    694 	{ PR_1_READ_EA_BLOCK,
    695 	  N_("Error reading @a @b %b for @i %i.  "),
    696 	  PROMPT_CLEAR, 0 },
    697 
    698 	/* Invalid extended attribute block */
    699 	{ PR_1_BAD_EA_BLOCK,
    700 	  N_("@i %i has a bad @a @b %b.  "),
    701 	  PROMPT_CLEAR, 0 },
    702 
    703 	/* Error reading Extended Attribute block while fixing refcount */
    704 	{ PR_1_EXTATTR_READ_ABORT,
    705 	  N_("Error reading @a @b %b (%m).  "),
    706 	  PROMPT_ABORT, 0 },
    707 
    708 	/* Extended attribute reference count incorrect */
    709 	{ PR_1_EXTATTR_REFCOUNT,
    710 	  N_("@a @b %b has reference count %r, @s %N.  "),
    711 	  PROMPT_FIX, 0 },
    712 
    713 	/* Error writing Extended Attribute block while fixing refcount */
    714 	{ PR_1_EXTATTR_WRITE,
    715 	  N_("Error writing @a @b %b (%m).  "),
    716 	  PROMPT_ABORT, 0 },
    717 
    718 	/* Multiple EA blocks not supported */
    719 	{ PR_1_EA_MULTI_BLOCK,
    720 	  N_("@a @b %b has h_@bs > 1.  "),
    721 	  PROMPT_CLEAR, 0},
    722 
    723 	/* Error allocating EA region allocation structure */
    724 	{ PR_1_EA_ALLOC_REGION,
    725 	  N_("@A @a @b %b.  "),
    726 	  PROMPT_ABORT, 0},
    727 
    728 	/* Error EA allocation collision */
    729 	{ PR_1_EA_ALLOC_COLLISION,
    730 	  N_("@a @b %b is corrupt (allocation collision).  "),
    731 	  PROMPT_CLEAR, 0},
    732 
    733 	/* Bad extended attribute name */
    734 	{ PR_1_EA_BAD_NAME,
    735 	  N_("@a @b %b is corrupt (@n name).  "),
    736 	  PROMPT_CLEAR, 0},
    737 
    738 	/* Bad extended attribute value */
    739 	{ PR_1_EA_BAD_VALUE,
    740 	  N_("@a @b %b is corrupt (@n value).  "),
    741 	  PROMPT_CLEAR, 0},
    742 
    743 	/* Inode too big (latch question) */
    744 	{ PR_1_INODE_TOOBIG,
    745 	  N_("@i %i is too big.  "), PROMPT_TRUNCATE, 0 },
    746 
    747 	/* Directory too big */
    748 	{ PR_1_TOOBIG_DIR,
    749 	  N_("%B (%b) causes @d to be too big.  "),
    750 	  PROMPT_CLEAR, PR_LATCH_TOOBIG },
    751 
    752 	/* Regular file too big */
    753 	{ PR_1_TOOBIG_REG,
    754 	  N_("%B (%b) causes file to be too big.  "),
    755 	  PROMPT_CLEAR, PR_LATCH_TOOBIG },
    756 
    757 	/* Symlink too big */
    758 	{ PR_1_TOOBIG_SYMLINK,
    759 	  N_("%B (%b) causes symlink to be too big.  "),
    760 	  PROMPT_CLEAR, PR_LATCH_TOOBIG },
    761 
    762 	/* INDEX_FL flag set on a non-HTREE filesystem */
    763 	{ PR_1_HTREE_SET,
    764 	  N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
    765 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
    766 
    767 	/* INDEX_FL flag set on a non-directory */
    768 	{ PR_1_HTREE_NODIR,
    769 	  N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
    770 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
    771 
    772 	/* Invalid root node in HTREE directory */
    773 	{ PR_1_HTREE_BADROOT,
    774 	  N_("@h %i has an @n root node.\n"),
    775 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
    776 
    777 	/* Unsupported hash version in HTREE directory */
    778 	{ PR_1_HTREE_HASHV,
    779 	  N_("@h %i has an unsupported hash version (%N)\n"),
    780 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
    781 
    782 	/* Incompatible flag in HTREE root node */
    783 	{ PR_1_HTREE_INCOMPAT,
    784 	  N_("@h %i uses an incompatible htree root node flag.\n"),
    785 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
    786 
    787 	/* HTREE too deep */
    788 	{ PR_1_HTREE_DEPTH,
    789 	  N_("@h %i has a tree depth (%N) which is too big\n"),
    790 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
    791 
    792 	/* Bad block has indirect block that conflicts with filesystem block */
    793 	{ PR_1_BB_FS_BLOCK,
    794 	  N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
    795 	     "@f metadata.  "),
    796 	  PROMPT_CLEAR, PR_LATCH_BBLOCK },
    797 
    798 	/* Resize inode failed */
    799 	{ PR_1_RESIZE_INODE_CREATE,
    800 	  N_("Resize @i (re)creation failed: %m."),
    801 	  PROMPT_ABORT, 0 },
    802 
    803 	/* invalid inode->i_extra_isize */
    804 	{ PR_1_EXTRA_ISIZE,
    805 	  N_("@i %i has a extra size (%IS) which is @n\n"),
    806 	  PROMPT_FIX, PR_PREEN_OK },
    807 
    808 	/* invalid ea entry->e_name_len */
    809 	{ PR_1_ATTR_NAME_LEN,
    810 	  N_("@a in @i %i has a namelen (%N) which is @n\n"),
    811 	  PROMPT_CLEAR, PR_PREEN_OK },
    812 
    813 	/* invalid ea entry->e_value_offs */
    814 	{ PR_1_ATTR_VALUE_OFFSET,
    815 	  N_("@a in @i %i has a value offset (%N) which is @n\n"),
    816 	  PROMPT_CLEAR, PR_PREEN_OK },
    817 
    818 	/* invalid ea entry->e_value_block */
    819 	{ PR_1_ATTR_VALUE_BLOCK,
    820 	  N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
    821 	  PROMPT_CLEAR, PR_PREEN_OK },
    822 
    823 	/* invalid ea entry->e_value_size */
    824 	{ PR_1_ATTR_VALUE_SIZE,
    825 	  N_("@a in @i %i has a value size (%N) which is @n\n"),
    826 	  PROMPT_CLEAR, PR_PREEN_OK },
    827 
    828 	/* invalid ea entry->e_hash */
    829 	{ PR_1_ATTR_HASH,
    830 	  N_("@a in @i %i has a hash (%N) which is @n\n"),
    831 	  PROMPT_CLEAR, PR_PREEN_OK },
    832 
    833 	/* inode appears to be a directory */
    834 	{ PR_1_TREAT_AS_DIRECTORY,
    835 	  N_("@i %i is a %It but it looks like it is really a directory.\n"),
    836 	  PROMPT_FIX, 0 },
    837 
    838 	/* Error while reading extent tree */
    839 	{ PR_1_READ_EXTENT,
    840 	  N_("Error while reading over @x tree in @i %i: %m\n"),
    841 	  PROMPT_CLEAR_INODE, 0 },
    842 
    843 	/* Failure to iterate extents */
    844 	{ PR_1_EXTENT_ITERATE_FAILURE,
    845 	  N_("Failed to iterate extents in @i %i\n"
    846 	     "\t(op %s, blk %b, lblk %c): %m\n"),
    847 	  PROMPT_CLEAR_INODE, 0 },
    848 
    849 	/* Bad starting block in extent */
    850 	{ PR_1_EXTENT_BAD_START_BLK,
    851 	  N_("@i %i has an @n extent\n\t(logical @b %c, @n physical @b %b, len %N)\n"),
    852 	  PROMPT_CLEAR, 0 },
    853 
    854 	/* Extent ends beyond filesystem */
    855 	{ PR_1_EXTENT_ENDS_BEYOND,
    856 	  N_("@i %i has an @n extent\n\t(logical @b %c, physical @b %b, @n len %N)\n"),
    857 	  PROMPT_CLEAR, 0 },
    858 
    859 	/* EXTENTS_FL flag set on a non-extents filesystem */
    860 	{ PR_1_EXTENTS_SET,
    861 	  N_("@i %i has EXTENTS_FL flag set on @f without extents support.\n"),
    862 	  PROMPT_CLEAR, 0 },
    863 
    864 	/* inode has extents, superblock missing INCOMPAT_EXTENTS feature */
    865 	{ PR_1_EXTENT_FEATURE,
    866 	  N_("@i %i is in extent format, but @S is missing EXTENTS feature\n"),
    867 	  PROMPT_FIX, 0 },
    868 
    869 	/* inode missing EXTENTS_FL, but is an extent inode */
    870 	{ PR_1_UNSET_EXTENT_FL,
    871 	  N_("@i %i missing EXTENT_FL, but is in extents format\n"),
    872 	  PROMPT_FIX, PR_PREEN_OK },
    873 
    874 	/* Fast symlink has EXTENTS_FL set */
    875 	{ PR_1_FAST_SYMLINK_EXTENT_FL,
    876 	  N_("Fast symlink %i has EXTENT_FL set.  "),
    877 	  PROMPT_CLEAR, 0 },
    878 
    879 	/* Extents are out of order */
    880 	{ PR_1_OUT_OF_ORDER_EXTENTS,
    881 	  N_("@i %i has out of order extents\n\t(@n logical @b %c, physical @b %b, len %N)\n"),
    882 	  PROMPT_CLEAR, 0 },
    883 
    884 	{ PR_1_EXTENT_HEADER_INVALID,
    885 	  N_("@i %i has an invalid extent node (blk %b, lblk %c)\n"),
    886 	  PROMPT_CLEAR, 0 },
    887 
    888 	/* Pass 1b errors */
    889 
    890 	/* Pass 1B: Rescan for duplicate/bad blocks */
    891 	{ PR_1B_PASS_HEADER,
    892 	  N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
    893 	  "Pass 1B: Rescanning for @m @bs\n"),
    894 	  PROMPT_NONE, 0 },
    895 
    896 	/* Duplicate/bad block(s) header */
    897 	{ PR_1B_DUP_BLOCK_HEADER,
    898 	  N_("@m @b(s) in @i %i:"),
    899 	  PROMPT_NONE, 0 },
    900 
    901 	/* Duplicate/bad block(s) in inode */
    902 	{ PR_1B_DUP_BLOCK,
    903 	  " %b",
    904 	  PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
    905 
    906 	/* Duplicate/bad block(s) end */
    907 	{ PR_1B_DUP_BLOCK_END,
    908 	  "\n",
    909 	  PROMPT_NONE, PR_PREEN_NOHDR },
    910 
    911 	/* Error while scanning inodes */
    912 	{ PR_1B_ISCAN_ERROR,
    913 	  N_("Error while scanning inodes (%i): %m\n"),
    914 	  PROMPT_NONE, PR_FATAL },
    915 
    916 	/* Error allocating inode bitmap */
    917 	{ PR_1B_ALLOCATE_IBITMAP_ERROR,
    918 	  N_("@A @i @B (@i_dup_map): %m\n"),
    919 	  PROMPT_NONE, PR_FATAL },
    920 
    921 	/* Error while iterating over blocks */
    922 	{ PR_1B_BLOCK_ITERATE,
    923 	  N_("Error while iterating over @bs in @i %i (%s): %m\n"),
    924 	  PROMPT_NONE, 0 },
    925 
    926 	/* Error adjusting EA refcount */
    927 	{ PR_1B_ADJ_EA_REFCOUNT,
    928 	  N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
    929 	  PROMPT_NONE, 0 },
    930 
    931 
    932 	/* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
    933 	{ PR_1C_PASS_HEADER,
    934 	  N_("Pass 1C: Scanning directories for @is with @m @bs\n"),
    935 	  PROMPT_NONE, 0 },
    936 
    937 
    938 	/* Pass 1D: Reconciling multiply-claimed blocks */
    939 	{ PR_1D_PASS_HEADER,
    940 	  N_("Pass 1D: Reconciling @m @bs\n"),
    941 	  PROMPT_NONE, 0 },
    942 
    943 	/* File has duplicate blocks */
    944 	{ PR_1D_DUP_FILE,
    945 	  N_("File %Q (@i #%i, mod time %IM) \n"
    946 	  "  has %r @m @b(s), shared with %N file(s):\n"),
    947 	  PROMPT_NONE, 0 },
    948 
    949 	/* List of files sharing duplicate blocks */
    950 	{ PR_1D_DUP_FILE_LIST,
    951 	  N_("\t%Q (@i #%i, mod time %IM)\n"),
    952 	  PROMPT_NONE, 0 },
    953 
    954 	/* File sharing blocks with filesystem metadata  */
    955 	{ PR_1D_SHARE_METADATA,
    956 	  N_("\t<@f metadata>\n"),
    957 	  PROMPT_NONE, 0 },
    958 
    959 	/* Report of how many duplicate/bad inodes */
    960 	{ PR_1D_NUM_DUP_INODES,
    961 	  N_("(There are %N @is containing @m @bs.)\n\n"),
    962 	  PROMPT_NONE, 0 },
    963 
    964 	/* Duplicated blocks already reassigned or cloned. */
    965 	{ PR_1D_DUP_BLOCKS_DEALT,
    966 	  N_("@m @bs already reassigned or cloned.\n\n"),
    967 	  PROMPT_NONE, 0 },
    968 
    969 	/* Clone duplicate/bad blocks? */
    970 	{ PR_1D_CLONE_QUESTION,
    971 	  "", PROMPT_CLONE, PR_NO_OK },
    972 
    973 	/* Delete file? */
    974 	{ PR_1D_DELETE_QUESTION,
    975 	  "", PROMPT_DELETE, 0 },
    976 
    977 	/* Couldn't clone file (error) */
    978 	{ PR_1D_CLONE_ERROR,
    979 	  N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
    980 
    981 	/* Pass 2 errors */
    982 
    983 	/* Pass 2: Checking directory structure */
    984 	{ PR_2_PASS_HEADER,
    985 	  N_("Pass 2: Checking @d structure\n"),
    986 	  PROMPT_NONE, 0 },
    987 
    988 	/* Bad inode number for '.' */
    989 	{ PR_2_BAD_INODE_DOT,
    990 	  N_("@n @i number for '.' in @d @i %i.\n"),
    991 	  PROMPT_FIX, 0 },
    992 
    993 	/* Directory entry has bad inode number */
    994 	{ PR_2_BAD_INO,
    995 	  N_("@E has @n @i #: %Di.\n"),
    996 	  PROMPT_CLEAR, 0 },
    997 
    998 	/* Directory entry has deleted or unused inode */
    999 	{ PR_2_UNUSED_INODE,
   1000 	  N_("@E has @D/unused @i %Di.  "),
   1001 	  PROMPT_CLEAR, PR_PREEN_OK },
   1002 
   1003 	/* Directry entry is link to '.' */
   1004 	{ PR_2_LINK_DOT,
   1005 	  N_("@E @L to '.'  "),
   1006 	  PROMPT_CLEAR, 0 },
   1007 
   1008 	/* Directory entry points to inode now located in a bad block */
   1009 	{ PR_2_BB_INODE,
   1010 	  N_("@E points to @i (%Di) located in a bad @b.\n"),
   1011 	  PROMPT_CLEAR, 0 },
   1012 
   1013 	/* Directory entry contains a link to a directory */
   1014 	{ PR_2_LINK_DIR,
   1015 	  N_("@E @L to @d %P (%Di).\n"),
   1016 	  PROMPT_CLEAR, 0 },
   1017 
   1018 	/* Directory entry contains a link to the root directry */
   1019 	{ PR_2_LINK_ROOT,
   1020 	  N_("@E @L to the @r.\n"),
   1021 	  PROMPT_CLEAR, 0 },
   1022 
   1023 	/* Directory entry has illegal characters in its name */
   1024 	{ PR_2_BAD_NAME,
   1025 	  N_("@E has illegal characters in its name.\n"),
   1026 	  PROMPT_FIX, 0 },
   1027 
   1028 	/* Missing '.' in directory inode */
   1029 	{ PR_2_MISSING_DOT,
   1030 	  N_("Missing '.' in @d @i %i.\n"),
   1031 	  PROMPT_FIX, 0 },
   1032 
   1033 	/* Missing '..' in directory inode */
   1034 	{ PR_2_MISSING_DOT_DOT,
   1035 	  N_("Missing '..' in @d @i %i.\n"),
   1036 	  PROMPT_FIX, 0 },
   1037 
   1038 	/* First entry in directory inode doesn't contain '.' */
   1039 	{ PR_2_1ST_NOT_DOT,
   1040 	  N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
   1041 	  PROMPT_FIX, 0 },
   1042 
   1043 	/* Second entry in directory inode doesn't contain '..' */
   1044 	{ PR_2_2ND_NOT_DOT_DOT,
   1045 	  N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
   1046 	  PROMPT_FIX, 0 },
   1047 
   1048 	/* i_faddr should be zero */
   1049 	{ PR_2_FADDR_ZERO,
   1050 	  N_("i_faddr @F %IF, @s zero.\n"),
   1051 	  PROMPT_CLEAR, 0 },
   1052 
   1053 	/* i_file_acl should be zero */
   1054 	{ PR_2_FILE_ACL_ZERO,
   1055 	  N_("i_file_acl @F %If, @s zero.\n"),
   1056 	  PROMPT_CLEAR, 0 },
   1057 
   1058 	/* i_dir_acl should be zero */
   1059 	{ PR_2_DIR_ACL_ZERO,
   1060 	  N_("i_dir_acl @F %Id, @s zero.\n"),
   1061 	  PROMPT_CLEAR, 0 },
   1062 
   1063 	/* i_frag should be zero */
   1064 	{ PR_2_FRAG_ZERO,
   1065 	  N_("i_frag @F %N, @s zero.\n"),
   1066 	  PROMPT_CLEAR, 0 },
   1067 
   1068 	/* i_fsize should be zero */
   1069 	{ PR_2_FSIZE_ZERO,
   1070 	  N_("i_fsize @F %N, @s zero.\n"),
   1071 	  PROMPT_CLEAR, 0 },
   1072 
   1073 	/* inode has bad mode */
   1074 	{ PR_2_BAD_MODE,
   1075 	  N_("@i %i (%Q) has @n mode (%Im).\n"),
   1076 	  PROMPT_CLEAR, 0 },
   1077 
   1078 	/* directory corrupted */
   1079 	{ PR_2_DIR_CORRUPTED,
   1080 	  N_("@d @i %i, %B, offset %N: @d corrupted\n"),
   1081 	  PROMPT_SALVAGE, 0 },
   1082 
   1083 	/* filename too long */
   1084 	{ PR_2_FILENAME_LONG,
   1085 	  N_("@d @i %i, %B, offset %N: filename too long\n"),
   1086 	  PROMPT_TRUNCATE, 0 },
   1087 
   1088 	/* Directory inode has a missing block (hole) */
   1089 	{ PR_2_DIRECTORY_HOLE,
   1090 	  N_("@d @i %i has an unallocated %B.  "),
   1091 	  PROMPT_ALLOCATE, 0 },
   1092 
   1093 	/* '.' is not NULL terminated */
   1094 	{ PR_2_DOT_NULL_TERM,
   1095 	  N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
   1096 	  PROMPT_FIX, 0 },
   1097 
   1098 	/* '..' is not NULL terminated */
   1099 	{ PR_2_DOT_DOT_NULL_TERM,
   1100 	  N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
   1101 	  PROMPT_FIX, 0 },
   1102 
   1103 	/* Illegal character device inode */
   1104 	{ PR_2_BAD_CHAR_DEV,
   1105 	  N_("@i %i (%Q) is an @I character @v.\n"),
   1106 	  PROMPT_CLEAR, 0 },
   1107 
   1108 	/* Illegal block device inode */
   1109 	{ PR_2_BAD_BLOCK_DEV,
   1110 	  N_("@i %i (%Q) is an @I @b @v.\n"),
   1111 	  PROMPT_CLEAR, 0 },
   1112 
   1113 	/* Duplicate '.' entry */
   1114 	{ PR_2_DUP_DOT,
   1115 	  N_("@E is duplicate '.' @e.\n"),
   1116 	  PROMPT_FIX, 0 },
   1117 
   1118 	/* Duplicate '..' entry */
   1119 	{ PR_2_DUP_DOT_DOT,
   1120 	  N_("@E is duplicate '..' @e.\n"),
   1121 	  PROMPT_FIX, 0 },
   1122 
   1123 	/* Internal error: couldn't find dir_info */
   1124 	{ PR_2_NO_DIRINFO,
   1125 	  N_("Internal error: couldn't find dir_info for %i.\n"),
   1126 	  PROMPT_NONE, PR_FATAL },
   1127 
   1128 	/* Final rec_len is wrong */
   1129 	{ PR_2_FINAL_RECLEN,
   1130 	  N_("@E has rec_len of %Dr, @s %N.\n"),
   1131 	  PROMPT_FIX, 0 },
   1132 
   1133 	/* Error allocating icount structure */
   1134 	{ PR_2_ALLOCATE_ICOUNT,
   1135 	  N_("@A icount structure: %m\n"),
   1136 	  PROMPT_NONE, PR_FATAL },
   1137 
   1138 	/* Error iterating over directory blocks */
   1139 	{ PR_2_DBLIST_ITERATE,
   1140 	  N_("Error iterating over @d @bs: %m\n"),
   1141 	  PROMPT_NONE, PR_FATAL },
   1142 
   1143 	/* Error reading directory block */
   1144 	{ PR_2_READ_DIRBLOCK,
   1145 	  N_("Error reading @d @b %b (@i %i): %m\n"),
   1146 	  PROMPT_CONTINUE, 0 },
   1147 
   1148 	/* Error writing directory block */
   1149 	{ PR_2_WRITE_DIRBLOCK,
   1150 	  N_("Error writing @d @b %b (@i %i): %m\n"),
   1151 	  PROMPT_CONTINUE, 0 },
   1152 
   1153 	/* Error allocating new directory block */
   1154 	{ PR_2_ALLOC_DIRBOCK,
   1155 	  N_("@A new @d @b for @i %i (%s): %m\n"),
   1156 	  PROMPT_NONE, 0 },
   1157 
   1158 	/* Error deallocating inode */
   1159 	{ PR_2_DEALLOC_INODE,
   1160 	  N_("Error deallocating @i %i: %m\n"),
   1161 	  PROMPT_NONE, PR_FATAL },
   1162 
   1163 	/* Directory entry for '.' is big.  Split? */
   1164 	{ PR_2_SPLIT_DOT,
   1165 	  N_("@d @e for '.' in %p (%i) is big.\n"),
   1166 	  PROMPT_SPLIT, PR_NO_OK },
   1167 
   1168 	/* Illegal FIFO inode */
   1169 	{ PR_2_BAD_FIFO,
   1170 	  N_("@i %i (%Q) is an @I FIFO.\n"),
   1171 	  PROMPT_CLEAR, 0 },
   1172 
   1173 	/* Illegal socket inode */
   1174 	{ PR_2_BAD_SOCKET,
   1175 	  N_("@i %i (%Q) is an @I socket.\n"),
   1176 	  PROMPT_CLEAR, 0 },
   1177 
   1178 	/* Directory filetype not set */
   1179 	{ PR_2_SET_FILETYPE,
   1180 	  N_("Setting filetype for @E to %N.\n"),
   1181 	  PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
   1182 
   1183 	/* Directory filetype incorrect */
   1184 	{ PR_2_BAD_FILETYPE,
   1185 	  N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
   1186 	  PROMPT_FIX, 0 },
   1187 
   1188 	/* Directory filetype set on filesystem */
   1189 	{ PR_2_CLEAR_FILETYPE,
   1190 	  N_("@E has filetype set.\n"),
   1191 	  PROMPT_CLEAR, PR_PREEN_OK },
   1192 
   1193 	/* Directory filename is null */
   1194 	{ PR_2_NULL_NAME,
   1195 	  N_("@E has a @z name.\n"),
   1196 	  PROMPT_CLEAR, 0 },
   1197 
   1198 	/* Invalid symlink */
   1199 	{ PR_2_INVALID_SYMLINK,
   1200 	  N_("Symlink %Q (@i #%i) is @n.\n"),
   1201 	  PROMPT_CLEAR, 0 },
   1202 
   1203 	/* i_file_acl (extended attribute block) is bad */
   1204 	{ PR_2_FILE_ACL_BAD,
   1205 	  N_("@a @b @F @n (%If).\n"),
   1206 	  PROMPT_CLEAR, 0 },
   1207 
   1208 	/* Filesystem contains large files, but has no such flag in sb */
   1209 	{ PR_2_FEATURE_LARGE_FILES,
   1210 	  N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
   1211 	  PROMPT_FIX, 0 },
   1212 
   1213 	/* Node in HTREE directory not referenced */
   1214 	{ PR_2_HTREE_NOTREF,
   1215 	  N_("@p @h %d: %B not referenced\n"),
   1216 	  PROMPT_NONE, 0 },
   1217 
   1218 	/* Node in HTREE directory referenced twice */
   1219 	{ PR_2_HTREE_DUPREF,
   1220 	  N_("@p @h %d: %B referenced twice\n"),
   1221 	  PROMPT_NONE, 0 },
   1222 
   1223 	/* Node in HTREE directory has bad min hash */
   1224 	{ PR_2_HTREE_MIN_HASH,
   1225 	  N_("@p @h %d: %B has bad min hash\n"),
   1226 	  PROMPT_NONE, 0 },
   1227 
   1228 	/* Node in HTREE directory has bad max hash */
   1229 	{ PR_2_HTREE_MAX_HASH,
   1230 	  N_("@p @h %d: %B has bad max hash\n"),
   1231 	  PROMPT_NONE, 0 },
   1232 
   1233 	/* Clear invalid HTREE directory */
   1234 	{ PR_2_HTREE_CLEAR,
   1235 	  N_("@n @h %d (%q).  "), PROMPT_CLEAR_HTREE, 0 },
   1236 
   1237 	/* Bad block in htree interior node */
   1238 	{ PR_2_HTREE_BADBLK,
   1239 	  N_("@p @h %d (%q): bad @b number %b.\n"),
   1240 	  PROMPT_CLEAR_HTREE, 0 },
   1241 
   1242 	/* Error adjusting EA refcount */
   1243 	{ PR_2_ADJ_EA_REFCOUNT,
   1244 	  N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
   1245 	  PROMPT_NONE, PR_FATAL },
   1246 
   1247 	/* Invalid HTREE root node */
   1248 	{ PR_2_HTREE_BAD_ROOT,
   1249 	  N_("@p @h %d: root node is @n\n"),
   1250 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
   1251 
   1252 	/* Invalid HTREE limit */
   1253 	{ PR_2_HTREE_BAD_LIMIT,
   1254 	  N_("@p @h %d: %B has @n limit (%N)\n"),
   1255 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
   1256 
   1257 	/* Invalid HTREE count */
   1258 	{ PR_2_HTREE_BAD_COUNT,
   1259 	  N_("@p @h %d: %B has @n count (%N)\n"),
   1260 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
   1261 
   1262 	/* HTREE interior node has out-of-order hashes in table */
   1263 	{ PR_2_HTREE_HASH_ORDER,
   1264 	  N_("@p @h %d: %B has an unordered hash table\n"),
   1265 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
   1266 
   1267 	/* Node in HTREE directory has invalid depth */
   1268 	{ PR_2_HTREE_BAD_DEPTH,
   1269 	  N_("@p @h %d: %B has @n depth (%N)\n"),
   1270 	  PROMPT_NONE, 0 },
   1271 
   1272 	/* Duplicate directory entry found */
   1273 	{ PR_2_DUPLICATE_DIRENT,
   1274 	  N_("Duplicate @E found.  "),
   1275 	  PROMPT_CLEAR, 0 },
   1276 
   1277 	/* Non-unique filename found */
   1278 	{ PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
   1279 	  N_("@E has a non-unique filename.\nRename to %s"),
   1280 	  PROMPT_NULL, 0 },
   1281 
   1282 	/* Duplicate directory entry found */
   1283 	{ PR_2_REPORT_DUP_DIRENT,
   1284 	  N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
   1285 	  PROMPT_NONE, 0 },
   1286 
   1287 	/* i_blocks_hi should be zero */
   1288 	{ PR_2_BLOCKS_HI_ZERO,
   1289 	  N_("i_blocks_hi @F %N, @s zero.\n"),
   1290 	  PROMPT_CLEAR, 0 },
   1291 
   1292 	/* Unexpected HTREE block */
   1293 	{ PR_2_UNEXPECTED_HTREE_BLOCK,
   1294 	  N_("Unexpected @b in @h %d (%q).\n"), PROMPT_CLEAR_HTREE, 0 },
   1295 
   1296 	/* Inode found in group where _INODE_UNINIT is set */
   1297 	{ PR_2_INOREF_BG_INO_UNINIT,
   1298 	  N_("@E references @i %Di in @g %g where _INODE_UNINIT is set.\n"),
   1299 	  PROMPT_FIX, PR_PREEN_OK },
   1300 
   1301 	/* Inode found in group unused inodes area */
   1302 	{ PR_2_INOREF_IN_UNUSED,
   1303 	  N_("@E references @i %Di found in @g %g's unused inodes area.\n"),
   1304 	  PROMPT_FIX, PR_PREEN_OK },
   1305 
   1306 	/* i_blocks_hi should be zero */
   1307 	{ PR_2_I_FILE_ACL_HI_ZERO,
   1308 	  N_("i_file_acl_hi @F %N, @s zero.\n"),
   1309 	  PROMPT_CLEAR, PR_PREEN_OK },
   1310 
   1311 	/* Pass 3 errors */
   1312 
   1313 	/* Pass 3: Checking directory connectivity */
   1314 	{ PR_3_PASS_HEADER,
   1315 	  N_("Pass 3: Checking @d connectivity\n"),
   1316 	  PROMPT_NONE, 0 },
   1317 
   1318 	/* Root inode not allocated */
   1319 	{ PR_3_NO_ROOT_INODE,
   1320 	  N_("@r not allocated.  "),
   1321 	  PROMPT_ALLOCATE, 0 },
   1322 
   1323 	/* No room in lost+found */
   1324 	{ PR_3_EXPAND_LF_DIR,
   1325 	  N_("No room in @l @d.  "),
   1326 	  PROMPT_EXPAND, 0 },
   1327 
   1328 	/* Unconnected directory inode */
   1329 	{ PR_3_UNCONNECTED_DIR,
   1330 	  N_("Unconnected @d @i %i (%p)\n"),
   1331 	  PROMPT_CONNECT, 0 },
   1332 
   1333 	/* /lost+found not found */
   1334 	{ PR_3_NO_LF_DIR,
   1335 	  N_("/@l not found.  "),
   1336 	  PROMPT_CREATE, PR_PREEN_OK },
   1337 
   1338 	/* .. entry is incorrect */
   1339 	{ PR_3_BAD_DOT_DOT,
   1340 	  N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
   1341 	  PROMPT_FIX, 0 },
   1342 
   1343 	/* Bad or non-existent /lost+found.  Cannot reconnect */
   1344 	{ PR_3_NO_LPF,
   1345 	  N_("Bad or non-existent /@l.  Cannot reconnect.\n"),
   1346 	  PROMPT_NONE, 0 },
   1347 
   1348 	/* Could not expand /lost+found */
   1349 	{ PR_3_CANT_EXPAND_LPF,
   1350 	  N_("Could not expand /@l: %m\n"),
   1351 	  PROMPT_NONE, 0 },
   1352 
   1353 	/* Could not reconnect inode */
   1354 	{ PR_3_CANT_RECONNECT,
   1355 	  N_("Could not reconnect %i: %m\n"),
   1356 	  PROMPT_NONE, 0 },
   1357 
   1358 	/* Error while trying to find /lost+found */
   1359 	{ PR_3_ERR_FIND_LPF,
   1360 	  N_("Error while trying to find /@l: %m\n"),
   1361 	  PROMPT_NONE, 0 },
   1362 
   1363 	/* Error in ext2fs_new_block while creating /lost+found */
   1364 	{ PR_3_ERR_LPF_NEW_BLOCK,
   1365 	  N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
   1366 	  PROMPT_NONE, 0 },
   1367 
   1368 	/* Error in ext2fs_new_inode while creating /lost+found */
   1369 	{ PR_3_ERR_LPF_NEW_INODE,
   1370 	  N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
   1371 	  PROMPT_NONE, 0 },
   1372 
   1373 	/* Error in ext2fs_new_dir_block while creating /lost+found */
   1374 	{ PR_3_ERR_LPF_NEW_DIR_BLOCK,
   1375 	  N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
   1376 	  PROMPT_NONE, 0 },
   1377 
   1378 	/* Error while writing directory block for /lost+found */
   1379 	{ PR_3_ERR_LPF_WRITE_BLOCK,
   1380 	  N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
   1381 	  PROMPT_NONE, 0 },
   1382 
   1383 	/* Error while adjusting inode count */
   1384 	{ PR_3_ADJUST_INODE,
   1385 	  N_("Error while adjusting @i count on @i %i\n"),
   1386 	  PROMPT_NONE, 0 },
   1387 
   1388 	/* Couldn't fix parent directory -- error */
   1389 	{ PR_3_FIX_PARENT_ERR,
   1390 	  N_("Couldn't fix parent of @i %i: %m\n\n"),
   1391 	  PROMPT_NONE, 0 },
   1392 
   1393 	/* Couldn't fix parent directory -- couldn't find it */
   1394 	{ PR_3_FIX_PARENT_NOFIND,
   1395 	  N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
   1396 	  PROMPT_NONE, 0 },
   1397 
   1398 	/* Error allocating inode bitmap */
   1399 	{ PR_3_ALLOCATE_IBITMAP_ERROR,
   1400 	  N_("@A @i @B (%N): %m\n"),
   1401 	  PROMPT_NONE, PR_FATAL },
   1402 
   1403 	/* Error creating root directory */
   1404 	{ PR_3_CREATE_ROOT_ERROR,
   1405 	  N_("Error creating root @d (%s): %m\n"),
   1406 	  PROMPT_NONE, PR_FATAL },
   1407 
   1408 	/* Error creating lost and found directory */
   1409 	{ PR_3_CREATE_LPF_ERROR,
   1410 	  N_("Error creating /@l @d (%s): %m\n"),
   1411 	  PROMPT_NONE, 0 },
   1412 
   1413 	/* Root inode is not directory; aborting */
   1414 	{ PR_3_ROOT_NOT_DIR_ABORT,
   1415 	  N_("@r is not a @d; aborting.\n"),
   1416 	  PROMPT_NONE, PR_FATAL },
   1417 
   1418 	/* Cannot proceed without a root inode. */
   1419 	{ PR_3_NO_ROOT_INODE_ABORT,
   1420 	  N_("Cannot proceed without a @r.\n"),
   1421 	  PROMPT_NONE, PR_FATAL },
   1422 
   1423 	/* Internal error: couldn't find dir_info */
   1424 	{ PR_3_NO_DIRINFO,
   1425 	  N_("Internal error: couldn't find dir_info for %i.\n"),
   1426 	  PROMPT_NONE, PR_FATAL },
   1427 
   1428 	/* Lost+found not a directory */
   1429 	{ PR_3_LPF_NOTDIR,
   1430 	  N_("/@l is not a @d (ino=%i)\n"),
   1431 	  PROMPT_UNLINK, 0 },
   1432 
   1433 	/* Pass 3A Directory Optimization	*/
   1434 
   1435 	/* Pass 3A: Optimizing directories */
   1436 	{ PR_3A_PASS_HEADER,
   1437 	  N_("Pass 3A: Optimizing directories\n"),
   1438 	  PROMPT_NONE, PR_PREEN_NOMSG },
   1439 
   1440 	/* Error iterating over directories */
   1441 	{ PR_3A_OPTIMIZE_ITER,
   1442 	  N_("Failed to create dirs_to_hash iterator: %m\n"),
   1443 	  PROMPT_NONE, 0 },
   1444 
   1445 	/* Error rehash directory */
   1446 	{ PR_3A_OPTIMIZE_DIR_ERR,
   1447 	  N_("Failed to optimize directory %q (%d): %m\n"),
   1448 	  PROMPT_NONE, 0 },
   1449 
   1450 	/* Rehashing dir header */
   1451 	{ PR_3A_OPTIMIZE_DIR_HEADER,
   1452 	  N_("Optimizing directories: "),
   1453 	  PROMPT_NONE, PR_MSG_ONLY },
   1454 
   1455 	/* Rehashing directory %d */
   1456 	{ PR_3A_OPTIMIZE_DIR,
   1457 	  " %d",
   1458 	  PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
   1459 
   1460 	/* Rehashing dir end */
   1461 	{ PR_3A_OPTIMIZE_DIR_END,
   1462 	  "\n",
   1463 	  PROMPT_NONE, PR_PREEN_NOHDR },
   1464 
   1465 	/* Pass 4 errors */
   1466 
   1467 	/* Pass 4: Checking reference counts */
   1468 	{ PR_4_PASS_HEADER,
   1469 	  N_("Pass 4: Checking reference counts\n"),
   1470 	  PROMPT_NONE, 0 },
   1471 
   1472 	/* Unattached zero-length inode */
   1473 	{ PR_4_ZERO_LEN_INODE,
   1474 	  N_("@u @z @i %i.  "),
   1475 	  PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
   1476 
   1477 	/* Unattached inode */
   1478 	{ PR_4_UNATTACHED_INODE,
   1479 	  N_("@u @i %i\n"),
   1480 	  PROMPT_CONNECT, 0 },
   1481 
   1482 	/* Inode ref count wrong */
   1483 	{ PR_4_BAD_REF_COUNT,
   1484 	  N_("@i %i ref count is %Il, @s %N.  "),
   1485 	  PROMPT_FIX, PR_PREEN_OK },
   1486 
   1487 	{ PR_4_INCONSISTENT_COUNT,
   1488 	  N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
   1489 	  "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
   1490 	  "@i_link_info[%i] is %N, @i.i_links_count is %Il.  "
   1491 	  "They @s the same!\n"),
   1492 	  PROMPT_NONE, 0 },
   1493 
   1494 	/* Pass 5 errors */
   1495 
   1496 	/* Pass 5: Checking group summary information */
   1497 	{ PR_5_PASS_HEADER,
   1498 	  N_("Pass 5: Checking @g summary information\n"),
   1499 	  PROMPT_NONE, 0 },
   1500 
   1501 	/* Padding at end of inode bitmap is not set. */
   1502 	{ PR_5_INODE_BMAP_PADDING,
   1503 	  N_("Padding at end of @i @B is not set. "),
   1504 	  PROMPT_FIX, PR_PREEN_OK },
   1505 
   1506 	/* Padding at end of block bitmap is not set. */
   1507 	{ PR_5_BLOCK_BMAP_PADDING,
   1508 	  N_("Padding at end of @b @B is not set. "),
   1509 	  PROMPT_FIX, PR_PREEN_OK },
   1510 
   1511 	/* Block bitmap differences header */
   1512 	{ PR_5_BLOCK_BITMAP_HEADER,
   1513 	  N_("@b @B differences: "),
   1514 	  PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
   1515 
   1516 	/* Block not used, but marked in bitmap */
   1517 	{ PR_5_BLOCK_UNUSED,
   1518 	  " -%b",
   1519 	  PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1520 
   1521 	/* Block used, but not marked used in bitmap */
   1522 	{ PR_5_BLOCK_USED,
   1523 	  " +%b",
   1524 	  PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1525 
   1526 	/* Block bitmap differences end */
   1527 	{ PR_5_BLOCK_BITMAP_END,
   1528 	  "\n",
   1529 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1530 
   1531 	/* Inode bitmap differences header */
   1532 	{ PR_5_INODE_BITMAP_HEADER,
   1533 	  N_("@i @B differences: "),
   1534 	  PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
   1535 
   1536 	/* Inode not used, but marked in bitmap */
   1537 	{ PR_5_INODE_UNUSED,
   1538 	  " -%i",
   1539 	  PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1540 
   1541 	/* Inode used, but not marked used in bitmap */
   1542 	{ PR_5_INODE_USED,
   1543 	  " +%i",
   1544 	  PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1545 
   1546 	/* Inode bitmap differences end */
   1547 	{ PR_5_INODE_BITMAP_END,
   1548 	  "\n",
   1549 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1550 
   1551 	/* Free inodes count for group wrong */
   1552 	{ PR_5_FREE_INODE_COUNT_GROUP,
   1553 	  N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
   1554 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1555 
   1556 	/* Directories count for group wrong */
   1557 	{ PR_5_FREE_DIR_COUNT_GROUP,
   1558 	  N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
   1559 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1560 
   1561 	/* Free inodes count wrong */
   1562 	{ PR_5_FREE_INODE_COUNT,
   1563 	  N_("Free @is count wrong (%i, counted=%j).\n"),
   1564 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1565 
   1566 	/* Free blocks count for group wrong */
   1567 	{ PR_5_FREE_BLOCK_COUNT_GROUP,
   1568 	  N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
   1569 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1570 
   1571 	/* Free blocks count wrong */
   1572 	{ PR_5_FREE_BLOCK_COUNT,
   1573 	  N_("Free @bs count wrong (%b, counted=%c).\n"),
   1574 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1575 
   1576 	/* Programming error: bitmap endpoints don't match */
   1577 	{ PR_5_BMAP_ENDPOINTS,
   1578 	  N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
   1579 	  "match calculated @B endpoints (%i, %j)\n"),
   1580 	  PROMPT_NONE, PR_FATAL },
   1581 
   1582 	/* Internal error: fudging end of bitmap */
   1583 	{ PR_5_FUDGE_BITMAP_ERROR,
   1584 	  N_("Internal error: fudging end of bitmap (%N)\n"),
   1585 	  PROMPT_NONE, PR_FATAL },
   1586 
   1587 	/* Error copying in replacement inode bitmap */
   1588 	{ PR_5_COPY_IBITMAP_ERROR,
   1589 	  N_("Error copying in replacement @i @B: %m\n"),
   1590 	  PROMPT_NONE, PR_FATAL },
   1591 
   1592 	/* Error copying in replacement block bitmap */
   1593 	{ PR_5_COPY_BBITMAP_ERROR,
   1594 	  N_("Error copying in replacement @b @B: %m\n"),
   1595 	  PROMPT_NONE, PR_FATAL },
   1596 
   1597 	/* Block range not used, but marked in bitmap */
   1598 	{ PR_5_BLOCK_RANGE_UNUSED,
   1599 	  " -(%b--%c)",
   1600 	  PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1601 
   1602 	/* Block range used, but not marked used in bitmap */
   1603 	{ PR_5_BLOCK_RANGE_USED,
   1604 	  " +(%b--%c)",
   1605 	  PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1606 
   1607 	/* Inode range not used, but marked in bitmap */
   1608 	{ PR_5_INODE_RANGE_UNUSED,
   1609 	  " -(%i--%j)",
   1610 	  PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1611 
   1612 	/* Inode range used, but not marked used in bitmap */
   1613 	{ PR_5_INODE_RANGE_USED,
   1614 	  " +(%i--%j)",
   1615 	  PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1616 
   1617 	/* Group N block(s) in use but group is marked BLOCK_UNINIT */
   1618 	{ PR_5_BLOCK_UNINIT,
   1619 	  N_("@g %g @b(s) in use but @g is marked BLOCK_UNINIT\n"),
   1620 	  PROMPT_FIX, PR_PREEN_OK },
   1621 
   1622 	/* Group N inode(s) in use but group is marked INODE_UNINIT */
   1623 	{ PR_5_INODE_UNINIT,
   1624 	  N_("@g %g @i(s) in use but @g is marked INODE_UNINIT\n"),
   1625 	  PROMPT_FIX, PR_PREEN_OK },
   1626 
   1627 	/* Post-Pass 5 errors */
   1628 
   1629 	/* Recreate journal if E2F_FLAG_JOURNAL_INODE flag is set */
   1630 	{ PR_6_RECREATE_JOURNAL,
   1631 	  N_("Recreate @j"),
   1632 	  PROMPT_NULL, PR_PREEN_OK | PR_NO_OK },
   1633 
   1634 	{ 0 }
   1635 };
   1636 
   1637 /*
   1638  * This is the latch flags register.  It allows several problems to be
   1639  * "latched" together.  This means that the user has to answer but one
   1640  * question for the set of problems, and all of the associated
   1641  * problems will be either fixed or not fixed.
   1642  */
   1643 static struct latch_descr pr_latch_info[] = {
   1644 	{ PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
   1645 	{ PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
   1646 	{ PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
   1647 	{ PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
   1648 	{ PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
   1649 	{ PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
   1650 	{ PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
   1651 	{ PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
   1652 	{ PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
   1653 	{ PR_LATCH_BG_CHECKSUM, PR_0_GDT_CSUM_LATCH, 0 },
   1654 	{ -1, 0, 0 },
   1655 };
   1656 
   1657 static struct e2fsck_problem *find_problem(problem_t code)
   1658 {
   1659 	int	i;
   1660 
   1661 	for (i=0; problem_table[i].e2p_code; i++) {
   1662 		if (problem_table[i].e2p_code == code)
   1663 			return &problem_table[i];
   1664 	}
   1665 	return 0;
   1666 }
   1667 
   1668 static struct latch_descr *find_latch(int code)
   1669 {
   1670 	int	i;
   1671 
   1672 	for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
   1673 		if (pr_latch_info[i].latch_code == code)
   1674 			return &pr_latch_info[i];
   1675 	}
   1676 	return 0;
   1677 }
   1678 
   1679 int end_problem_latch(e2fsck_t ctx, int mask)
   1680 {
   1681 	struct latch_descr *ldesc;
   1682 	struct problem_context pctx;
   1683 	int answer = -1;
   1684 
   1685 	ldesc = find_latch(mask);
   1686 	if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
   1687 		clear_problem_context(&pctx);
   1688 		answer = fix_problem(ctx, ldesc->end_message, &pctx);
   1689 	}
   1690 	ldesc->flags &= ~(PRL_VARIABLE);
   1691 	return answer;
   1692 }
   1693 
   1694 int set_latch_flags(int mask, int setflags, int clearflags)
   1695 {
   1696 	struct latch_descr *ldesc;
   1697 
   1698 	ldesc = find_latch(mask);
   1699 	if (!ldesc)
   1700 		return -1;
   1701 	ldesc->flags |= setflags;
   1702 	ldesc->flags &= ~clearflags;
   1703 	return 0;
   1704 }
   1705 
   1706 int get_latch_flags(int mask, int *value)
   1707 {
   1708 	struct latch_descr *ldesc;
   1709 
   1710 	ldesc = find_latch(mask);
   1711 	if (!ldesc)
   1712 		return -1;
   1713 	*value = ldesc->flags;
   1714 	return 0;
   1715 }
   1716 
   1717 void clear_problem_context(struct problem_context *ctx)
   1718 {
   1719 	memset(ctx, 0, sizeof(struct problem_context));
   1720 	ctx->blkcount = -1;
   1721 	ctx->group = -1;
   1722 }
   1723 
   1724 static void reconfigure_bool(e2fsck_t ctx, struct e2fsck_problem *ptr,
   1725 			     const char *key, int mask, const char *name)
   1726 {
   1727 	int	bool;
   1728 
   1729 	bool = (ptr->flags & mask);
   1730 	profile_get_boolean(ctx->profile, "problems", key, name, bool, &bool);
   1731 	if (bool)
   1732 		ptr->flags |= mask;
   1733 	else
   1734 		ptr->flags &= ~mask;
   1735 }
   1736 
   1737 
   1738 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
   1739 {
   1740 	ext2_filsys fs = ctx->fs;
   1741 	struct e2fsck_problem *ptr;
   1742 	struct latch_descr *ldesc = 0;
   1743 	const char *message;
   1744 	int		def_yn, answer, ans, broken_system_clock;
   1745 	int		print_answer = 0;
   1746 	int		suppress = 0;
   1747 
   1748 	ptr = find_problem(code);
   1749 	if (!ptr) {
   1750 		printf(_("Unhandled error code (0x%x)!\n"), code);
   1751 		return 0;
   1752 	}
   1753 	if (!(ptr->flags & PR_CONFIG)) {
   1754 		char	key[9], *new_desc;
   1755 
   1756 		if ((code == PR_0_FUTURE_SB_LAST_MOUNT) ||
   1757 		    (code == PR_0_FUTURE_SB_LAST_WRITE)) {
   1758 			profile_get_boolean(ctx->profile, "options",
   1759 					    "broken_system_clock", 0, 0,
   1760 					    &broken_system_clock);
   1761 			if (broken_system_clock)
   1762 				ptr->flags |= PR_PREEN_OK;
   1763 		}
   1764 
   1765 		sprintf(key, "0x%06x", code);
   1766 
   1767 		profile_get_string(ctx->profile, "problems", key,
   1768 				   "description", 0, &new_desc);
   1769 		if (new_desc)
   1770 			ptr->e2p_description = new_desc;
   1771 
   1772 		reconfigure_bool(ctx, ptr, key, PR_PREEN_OK, "preen_ok");
   1773 		reconfigure_bool(ctx, ptr, key, PR_NO_OK, "no_ok");
   1774 		reconfigure_bool(ctx, ptr, key, PR_NO_DEFAULT, "no_default");
   1775 		reconfigure_bool(ctx, ptr, key, PR_MSG_ONLY, "print_message_only");
   1776 		reconfigure_bool(ctx, ptr, key, PR_PREEN_NOMSG, "preen_nomessage");
   1777 		reconfigure_bool(ctx, ptr, key, PR_NOCOLLATE, "no_collate");
   1778 		reconfigure_bool(ctx, ptr, key, PR_NO_NOMSG, "no_nomsg");
   1779 		reconfigure_bool(ctx, ptr, key, PR_PREEN_NOHDR, "preen_noheader");
   1780 
   1781 		ptr->flags |= PR_CONFIG;
   1782 	}
   1783 	def_yn = 1;
   1784 	if ((ptr->flags & PR_NO_DEFAULT) ||
   1785 	    ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
   1786 	    (ctx->options & E2F_OPT_NO))
   1787 		def_yn= 0;
   1788 
   1789 	/*
   1790 	 * Do special latch processing.  This is where we ask the
   1791 	 * latch question, if it exists
   1792 	 */
   1793 	if (ptr->flags & PR_LATCH_MASK) {
   1794 		ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
   1795 		if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
   1796 			ans = fix_problem(ctx, ldesc->question, pctx);
   1797 			if (ans == 1)
   1798 				ldesc->flags |= PRL_YES;
   1799 			if (ans == 0)
   1800 				ldesc->flags |= PRL_NO;
   1801 			ldesc->flags |= PRL_LATCHED;
   1802 		}
   1803 		if (ldesc->flags & PRL_SUPPRESS)
   1804 			suppress++;
   1805 	}
   1806 	if ((ptr->flags & PR_PREEN_NOMSG) &&
   1807 	    (ctx->options & E2F_OPT_PREEN))
   1808 		suppress++;
   1809 	if ((ptr->flags & PR_NO_NOMSG) &&
   1810 	    (ctx->options & E2F_OPT_NO))
   1811 		suppress++;
   1812 	if (!suppress) {
   1813 		message = ptr->e2p_description;
   1814 		if ((ctx->options & E2F_OPT_PREEN) &&
   1815 		    !(ptr->flags & PR_PREEN_NOHDR)) {
   1816 			printf("%s: ", ctx->device_name ?
   1817 			       ctx->device_name : ctx->filesystem_name);
   1818 		}
   1819 		if (*message)
   1820 			print_e2fsck_message(ctx, _(message), pctx, 1, 0);
   1821 	}
   1822 	if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
   1823 		preenhalt(ctx);
   1824 
   1825 	if (ptr->flags & PR_FATAL)
   1826 		fatal_error(ctx, 0);
   1827 
   1828 	if (ptr->prompt == PROMPT_NONE) {
   1829 		if (ptr->flags & PR_NOCOLLATE)
   1830 			answer = -1;
   1831 		else
   1832 			answer = def_yn;
   1833 	} else {
   1834 		if (ctx->options & E2F_OPT_PREEN) {
   1835 			answer = def_yn;
   1836 			if (!(ptr->flags & PR_PREEN_NOMSG))
   1837 				print_answer = 1;
   1838 		} else if ((ptr->flags & PR_LATCH_MASK) &&
   1839 			   (ldesc->flags & (PRL_YES | PRL_NO))) {
   1840 			if (!suppress)
   1841 				print_answer = 1;
   1842 			if (ldesc->flags & PRL_YES)
   1843 				answer = 1;
   1844 			else
   1845 				answer = 0;
   1846 		} else
   1847 			answer = ask(ctx, (ptr->prompt == PROMPT_NULL) ? "" :
   1848 				     _(prompt[(int) ptr->prompt]), def_yn);
   1849 		if (!answer && !(ptr->flags & PR_NO_OK))
   1850 			ext2fs_unmark_valid(fs);
   1851 
   1852 		if (print_answer)
   1853 			printf("%s.\n", answer ?
   1854 			       _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
   1855 
   1856 	}
   1857 
   1858 	if ((ptr->prompt == PROMPT_ABORT) && answer)
   1859 		fatal_error(ctx, 0);
   1860 
   1861 	if (ptr->flags & PR_AFTER_CODE)
   1862 		answer = fix_problem(ctx, ptr->second_code, pctx);
   1863 
   1864 	return answer;
   1865 }
   1866 
   1867 #ifdef UNITTEST
   1868 
   1869 #include <stdlib.h>
   1870 #include <stdio.h>
   1871 
   1872 errcode_t
   1873 profile_get_boolean(profile_t profile, const char *name, const char *subname,
   1874 		    const char *subsubname, int def_val, int *ret_boolean)
   1875 {
   1876 	return 0;
   1877 }
   1878 
   1879 void print_e2fsck_message(e2fsck_t ctx, const char *msg,
   1880 			  struct problem_context *pctx, int first,
   1881 			  int recurse)
   1882 {
   1883 	return;
   1884 }
   1885 
   1886 void fatal_error(e2fsck_t ctx, const char *msg)
   1887 {
   1888 	return;
   1889 }
   1890 
   1891 void preenhalt(e2fsck_t ctx)
   1892 {
   1893 	return;
   1894 }
   1895 
   1896 errcode_t
   1897 profile_get_string(profile_t profile, const char *name, const char *subname,
   1898 		   const char *subsubname, const char *def_val,
   1899 		   char **ret_string)
   1900 {
   1901 	return 0;
   1902 }
   1903 
   1904 int ask (e2fsck_t ctx, const char * string, int def)
   1905 {
   1906 	return 0;
   1907 }
   1908 
   1909 int verify_problem_table(e2fsck_t ctx)
   1910 {
   1911 	struct e2fsck_problem *curr, *prev = NULL;
   1912 	int rc = 0;
   1913 
   1914 	for (prev = NULL, curr = problem_table; curr->e2p_code; prev = curr++) {
   1915 		if (prev == NULL)
   1916 			continue;
   1917 
   1918 		if (curr->e2p_code > prev->e2p_code)
   1919 			continue;
   1920 
   1921 		if (curr->e2p_code == prev->e2p_code)
   1922 			fprintf(stderr, "*** Duplicate in problem table:\n");
   1923 		else
   1924 			fprintf(stderr, "*** Unordered problem table:\n");
   1925 
   1926 		fprintf(stderr, "curr code = 0x%08x: %s\n",
   1927 			curr->e2p_code, curr->e2p_description);
   1928 		fprintf(stderr, "*** prev code = 0x%08x: %s\n",
   1929 			prev->e2p_code, prev->e2p_description);
   1930 
   1931 		fprintf(stderr, "*** This is a %sprogramming error in e2fsck\n",
   1932 			(curr->e2p_code == prev->e2p_code) ? "fatal " : "");
   1933 
   1934 		rc = 1;
   1935 	}
   1936 
   1937 	return rc;
   1938 }
   1939 
   1940 int main(int argc, char *argv[])
   1941 {
   1942 	e2fsck_t ctx;
   1943 	int rc;
   1944 
   1945 	rc = verify_problem_table(ctx);
   1946 	if (rc == 0)
   1947 		printf("e2fsck problem table verified\n");
   1948 
   1949 	return rc;
   1950 }
   1951 #endif /* UNITTEST */
   1952