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 ext3 @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_("Ext3 @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_("Ext3 @j @S is corrupt.\n"),
    221 	  PROMPT_FIX, PR_PREEN_OK },
    222 
    223 	/* Superblock flag should be cleared */
    224 	{ PR_0_JOURNAL_HAS_JOURNAL,
    225 	  N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
    226 	  PROMPT_CLEAR, PR_PREEN_OK },
    227 
    228 	/* Superblock flag is incorrect */
    229 	{ PR_0_JOURNAL_RECOVER_SET,
    230 	  N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
    231 	  PROMPT_CLEAR, PR_PREEN_OK },
    232 
    233 	/* Journal has data, but recovery flag is clear */
    234 	{ PR_0_JOURNAL_RECOVERY_CLEAR,
    235 	  N_("ext3 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 	/* Ask if we should run the journal anyway */
    244 	{ PR_0_JOURNAL_RUN,
    245 	  N_("Run @j anyway"),
    246 	  PROMPT_NULL, 0 },
    247 
    248 	/* Run the journal by default */
    249 	{ PR_0_JOURNAL_RUN_DEFAULT,
    250 	  N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
    251 	  PROMPT_NONE, 0 },
    252 
    253 	/* Clearing orphan inode */
    254 	{ PR_0_ORPHAN_CLEAR_INODE,
    255 	  N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
    256 	  PROMPT_NONE, 0 },
    257 
    258 	/* Illegal block found in orphaned inode */
    259 	{ PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
    260 	   N_("@I @b #%B (%b) found in @o @i %i.\n"),
    261 	  PROMPT_NONE, 0 },
    262 
    263 	/* Already cleared block found in orphaned inode */
    264 	{ PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
    265 	   N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
    266 	  PROMPT_NONE, 0 },
    267 
    268 	/* Illegal orphan inode in superblock */
    269 	{ PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
    270 	  N_("@I @o @i %i in @S.\n"),
    271 	  PROMPT_NONE, 0 },
    272 
    273 	/* Illegal inode in orphaned inode list */
    274 	{ PR_0_ORPHAN_ILLEGAL_INODE,
    275 	  N_("@I @i %i in @o @i list.\n"),
    276 	  PROMPT_NONE, 0 },
    277 
    278 	/* Filesystem revision is 0, but feature flags are set */
    279 	{ PR_0_FS_REV_LEVEL,
    280 	  N_("@f has feature flag(s) set, but is a revision 0 @f.  "),
    281 	  PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
    282 
    283 	/* Journal superblock has an unknown read-only feature flag set */
    284 	{ PR_0_JOURNAL_UNSUPP_ROCOMPAT,
    285 	  N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
    286 	  PROMPT_ABORT, 0 },
    287 
    288 	/* Journal superblock has an unknown incompatible feature flag set */
    289 	{ PR_0_JOURNAL_UNSUPP_INCOMPAT,
    290 	  N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
    291 	  PROMPT_ABORT, 0 },
    292 
    293 	/* Journal has unsupported version number */
    294 	{ PR_0_JOURNAL_UNSUPP_VERSION,
    295 	  N_("@j version not supported by this e2fsck.\n"),
    296 	  PROMPT_ABORT, 0 },
    297 
    298 	/* Moving journal to hidden file */
    299 	{ PR_0_MOVE_JOURNAL,
    300 	  N_("Moving @j from /%s to hidden @i.\n\n"),
    301 	  PROMPT_NONE, 0 },
    302 
    303 	/* Error moving journal to hidden file */
    304 	{ PR_0_ERR_MOVE_JOURNAL,
    305 	  N_("Error moving @j: %m\n\n"),
    306 	  PROMPT_NONE, 0 },
    307 
    308 	/* Clearing V2 journal superblock */
    309 	{ PR_0_CLEAR_V2_JOURNAL,
    310 	  N_("Found @n V2 @j @S fields (from V1 @j).\n"
    311 	     "Clearing fields beyond the V1 @j @S...\n\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 is in the future.  "),
    338 	  PROMPT_FIX, PR_PREEN_OK | 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 is in the future.  "),
    343 	  PROMPT_FIX, PR_PREEN_OK | 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 	/* Pass 1 errors */
    355 
    356 	/* Pass 1: Checking inodes, blocks, and sizes */
    357 	{ PR_1_PASS_HEADER,
    358 	  N_("Pass 1: Checking @is, @bs, and sizes\n"),
    359 	  PROMPT_NONE, 0 },
    360 
    361 	/* Root directory is not an inode */
    362 	{ PR_1_ROOT_NO_DIR, N_("@r is not a @d.  "),
    363 	  PROMPT_CLEAR, 0 },
    364 
    365 	/* Root directory has dtime set */
    366 	{ PR_1_ROOT_DTIME,
    367 	  N_("@r has dtime set (probably due to old mke2fs).  "),
    368 	  PROMPT_FIX, PR_PREEN_OK },
    369 
    370 	/* Reserved inode has bad mode */
    371 	{ PR_1_RESERVED_BAD_MODE,
    372 	  N_("Reserved @i %i (%Q) has @n mode.  "),
    373 	  PROMPT_CLEAR, PR_PREEN_OK },
    374 
    375 	/* Deleted inode has zero dtime */
    376 	{ PR_1_ZERO_DTIME,
    377 	  N_("@D @i %i has zero dtime.  "),
    378 	  PROMPT_FIX, PR_PREEN_OK },
    379 
    380 	/* Inode in use, but dtime set */
    381 	{ PR_1_SET_DTIME,
    382 	  N_("@i %i is in use, but has dtime set.  "),
    383 	  PROMPT_FIX, PR_PREEN_OK },
    384 
    385 	/* Zero-length directory */
    386 	{ PR_1_ZERO_LENGTH_DIR,
    387 	  N_("@i %i is a @z @d.  "),
    388 	  PROMPT_CLEAR, PR_PREEN_OK },
    389 
    390 	/* Block bitmap conflicts with some other fs block */
    391 	{ PR_1_BB_CONFLICT,
    392 	  N_("@g %g's @b @B at %b @C.\n"),
    393 	  PROMPT_RELOCATE, 0 },
    394 
    395 	/* Inode bitmap conflicts with some other fs block */
    396 	{ PR_1_IB_CONFLICT,
    397 	  N_("@g %g's @i @B at %b @C.\n"),
    398 	  PROMPT_RELOCATE, 0 },
    399 
    400 	/* Inode table conflicts with some other fs block */
    401 	{ PR_1_ITABLE_CONFLICT,
    402 	  N_("@g %g's @i table at %b @C.\n"),
    403 	  PROMPT_RELOCATE, 0 },
    404 
    405 	/* Block bitmap is on a bad block */
    406 	{ PR_1_BB_BAD_BLOCK,
    407 	  N_("@g %g's @b @B (%b) is bad.  "),
    408 	  PROMPT_RELOCATE, 0 },
    409 
    410 	/* Inode bitmap is on a bad block */
    411 	{ PR_1_IB_BAD_BLOCK,
    412 	  N_("@g %g's @i @B (%b) is bad.  "),
    413 	  PROMPT_RELOCATE, 0 },
    414 
    415 	/* Inode has incorrect i_size */
    416 	{ PR_1_BAD_I_SIZE,
    417 	  N_("@i %i, i_size is %Is, @s %N.  "),
    418 	  PROMPT_FIX, PR_PREEN_OK },
    419 
    420 	/* Inode has incorrect i_blocks */
    421 	{ PR_1_BAD_I_BLOCKS,
    422 	  N_("@i %i, i_@bs is %Ib, @s %N.  "),
    423 	  PROMPT_FIX, PR_PREEN_OK },
    424 
    425 	/* Illegal blocknumber in inode */
    426 	{ PR_1_ILLEGAL_BLOCK_NUM,
    427 	  N_("@I @b #%B (%b) in @i %i.  "),
    428 	  PROMPT_CLEAR, PR_LATCH_BLOCK },
    429 
    430 	/* Block number overlaps fs metadata */
    431 	{ PR_1_BLOCK_OVERLAPS_METADATA,
    432 	  N_("@b #%B (%b) overlaps @f metadata in @i %i.  "),
    433 	  PROMPT_CLEAR, PR_LATCH_BLOCK },
    434 
    435 	/* Inode has illegal blocks (latch question) */
    436 	{ PR_1_INODE_BLOCK_LATCH,
    437 	  N_("@i %i has illegal @b(s).  "),
    438 	  PROMPT_CLEAR, 0 },
    439 
    440 	/* Too many bad blocks in inode */
    441 	{ PR_1_TOO_MANY_BAD_BLOCKS,
    442 	  N_("Too many illegal @bs in @i %i.\n"),
    443 	  PROMPT_CLEAR_INODE, PR_NO_OK },
    444 
    445 	/* Illegal block number in bad block inode */
    446 	{ PR_1_BB_ILLEGAL_BLOCK_NUM,
    447 	  N_("@I @b #%B (%b) in bad @b @i.  "),
    448 	  PROMPT_CLEAR, PR_LATCH_BBLOCK },
    449 
    450 	/* Bad block inode has illegal blocks (latch question) */
    451 	{ PR_1_INODE_BBLOCK_LATCH,
    452 	  N_("Bad @b @i has illegal @b(s).  "),
    453 	  PROMPT_CLEAR, 0 },
    454 
    455 	/* Duplicate or bad blocks in use! */
    456 	{ PR_1_DUP_BLOCKS_PREENSTOP,
    457 	  N_("Duplicate or bad @b in use!\n"),
    458 	  PROMPT_NONE, 0 },
    459 
    460 	/* Bad block used as bad block indirect block */
    461 	{ PR_1_BBINODE_BAD_METABLOCK,
    462 	  N_("Bad @b %b used as bad @b @i indirect @b.  "),
    463 	  PROMPT_CLEAR, PR_LATCH_BBLOCK },
    464 
    465 	/* Inconsistency can't be fixed prompt */
    466 	{ PR_1_BBINODE_BAD_METABLOCK_PROMPT,
    467 	  N_("\nThe bad @b @i has probably been corrupted.  You probably\n"
    468 	     "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
    469 	     "in the @f.\n"),
    470 	  PROMPT_CONTINUE, PR_PREEN_NOMSG },
    471 
    472 	/* Bad primary block */
    473 	{ PR_1_BAD_PRIMARY_BLOCK,
    474 	  N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
    475 	  PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
    476 
    477 	/* Bad primary block prompt */
    478 	{ PR_1_BAD_PRIMARY_BLOCK_PROMPT,
    479 	  N_("You can remove this @b from the bad @b list and hope\n"
    480 	     "that the @b is really OK.  But there are no guarantees.\n\n"),
    481 	  PROMPT_CLEAR, PR_PREEN_NOMSG },
    482 
    483 	/* Bad primary superblock */
    484 	{ PR_1_BAD_PRIMARY_SUPERBLOCK,
    485 	  N_("The primary @S (%b) is on the bad @b list.\n"),
    486 	  PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
    487 
    488 	/* Bad primary block group descriptors */
    489 	{ PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
    490 	  N_("Block %b in the primary @g descriptors "
    491 	  "is on the bad @b list\n"),
    492 	  PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
    493 
    494 	/* Bad superblock in group */
    495 	{ PR_1_BAD_SUPERBLOCK,
    496 	  N_("Warning: Group %g's @S (%b) is bad.\n"),
    497 	  PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
    498 
    499 	/* Bad block group descriptors in group */
    500 	{ PR_1_BAD_GROUP_DESCRIPTORS,
    501 	  N_("Warning: Group %g's copy of the @g descriptors has a bad "
    502 	  "@b (%b).\n"),
    503 	  PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
    504 
    505 	/* Block claimed for no reason */
    506 	{ PR_1_PROGERR_CLAIMED_BLOCK,
    507 	  N_("Programming error?  @b #%b claimed for no reason in "
    508 	  "process_bad_@b.\n"),
    509 	  PROMPT_NONE, PR_PREEN_OK },
    510 
    511 	/* Error allocating blocks for relocating metadata */
    512 	{ PR_1_RELOC_BLOCK_ALLOCATE,
    513 	  N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
    514 	  PROMPT_NONE, PR_PREEN_OK },
    515 
    516 	/* Error allocating block buffer during relocation process */
    517 	{ PR_1_RELOC_MEMORY_ALLOCATE,
    518 	  N_("@A @b buffer for relocating %s\n"),
    519 	  PROMPT_NONE, PR_PREEN_OK },
    520 
    521 	/* Relocating metadata group information from X to Y */
    522 	{ PR_1_RELOC_FROM_TO,
    523 	  N_("Relocating @g %g's %s from %b to %c...\n"),
    524 	  PROMPT_NONE, PR_PREEN_OK },
    525 
    526 	/* Relocating metatdata group information to X */
    527 	{ PR_1_RELOC_TO,
    528 	  N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
    529 	  PROMPT_NONE, PR_PREEN_OK },
    530 
    531 	/* Block read error during relocation process */
    532 	{ PR_1_RELOC_READ_ERR,
    533 	  N_("Warning: could not read @b %b of %s: %m\n"),
    534 	  PROMPT_NONE, PR_PREEN_OK },
    535 
    536 	/* Block write error during relocation process */
    537 	{ PR_1_RELOC_WRITE_ERR,
    538 	  N_("Warning: could not write @b %b for %s: %m\n"),
    539 	  PROMPT_NONE, PR_PREEN_OK },
    540 
    541 	/* Error allocating inode bitmap */
    542 	{ PR_1_ALLOCATE_IBITMAP_ERROR,
    543 	  N_("@A @i @B (%N): %m\n"),
    544 	  PROMPT_NONE, PR_FATAL },
    545 
    546 	/* Error allocating block bitmap */
    547 	{ PR_1_ALLOCATE_BBITMAP_ERROR,
    548 	  N_("@A @b @B (%N): %m\n"),
    549 	  PROMPT_NONE, PR_FATAL },
    550 
    551 	/* Error allocating icount structure */
    552 	{ PR_1_ALLOCATE_ICOUNT,
    553 	  N_("@A icount link information: %m\n"),
    554 	  PROMPT_NONE, PR_FATAL },
    555 
    556 	/* Error allocating dbcount */
    557 	{ PR_1_ALLOCATE_DBCOUNT,
    558 	  N_("@A @d @b array: %m\n"),
    559 	  PROMPT_NONE, PR_FATAL },
    560 
    561 	/* Error while scanning inodes */
    562 	{ PR_1_ISCAN_ERROR,
    563 	  N_("Error while scanning @is (%i): %m\n"),
    564 	  PROMPT_NONE, PR_FATAL },
    565 
    566 	/* Error while iterating over blocks */
    567 	{ PR_1_BLOCK_ITERATE,
    568 	  N_("Error while iterating over @bs in @i %i: %m\n"),
    569 	  PROMPT_NONE, PR_FATAL },
    570 
    571 	/* Error while storing inode count information */
    572 	{ PR_1_ICOUNT_STORE,
    573 	  N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
    574 	  PROMPT_NONE, PR_FATAL },
    575 
    576 	/* Error while storing directory block information */
    577 	{ PR_1_ADD_DBLOCK,
    578 	  N_("Error storing @d @b information "
    579 	  "(@i=%i, @b=%b, num=%N): %m\n"),
    580 	  PROMPT_NONE, PR_FATAL },
    581 
    582 	/* Error while reading inode (for clearing) */
    583 	{ PR_1_READ_INODE,
    584 	  N_("Error reading @i %i: %m\n"),
    585 	  PROMPT_NONE, PR_FATAL },
    586 
    587 	/* Suppress messages prompt */
    588 	{ PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
    589 
    590 	/* Imagic flag set on an inode when filesystem doesn't support it */
    591 	{ PR_1_SET_IMAGIC,
    592 	  N_("@i %i has imagic flag set.  "),
    593 	  PROMPT_CLEAR, 0 },
    594 
    595 	/* Immutable flag set on a device or socket inode */
    596 	{ PR_1_SET_IMMUTABLE,
    597 	  N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
    598 	     "or append-only flag set.  "),
    599 	  PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
    600 
    601 	/* Compression flag set on an inode when filesystem doesn't support it */
    602 	{ PR_1_COMPR_SET,
    603 	  N_("@i %i has @cion flag set on @f without @cion support.  "),
    604 	  PROMPT_CLEAR, 0 },
    605 
    606 	/* Non-zero size for device, fifo or socket inode */
    607 	{ PR_1_SET_NONZSIZE,
    608 	  N_("Special (@v/socket/fifo) @i %i has non-zero size.  "),
    609 	  PROMPT_FIX, PR_PREEN_OK },
    610 
    611 	/* Filesystem revision is 0, but feature flags are set */
    612 	{ PR_1_FS_REV_LEVEL,
    613 	  N_("@f has feature flag(s) set, but is a revision 0 @f.  "),
    614 	  PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
    615 
    616 	/* Journal inode is not in use, but contains data */
    617 	{ PR_1_JOURNAL_INODE_NOT_CLEAR,
    618 	  N_("@j @i is not in use, but contains data.  "),
    619 	  PROMPT_CLEAR, PR_PREEN_OK },
    620 
    621 	/* Journal has bad mode */
    622 	{ PR_1_JOURNAL_BAD_MODE,
    623 	  N_("@j is not regular file.  "),
    624 	  PROMPT_FIX, PR_PREEN_OK },
    625 
    626 	/* Deal with inodes that were part of orphan linked list */
    627 	{ PR_1_LOW_DTIME,
    628 	  N_("@i %i was part of the @o @i list.  "),
    629 	  PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
    630 
    631 	/* Deal with inodes that were part of corrupted orphan linked
    632 	   list (latch question) */
    633 	{ PR_1_ORPHAN_LIST_REFUGEES,
    634 	  N_("@is that were part of a corrupted orphan linked list found.  "),
    635 	  PROMPT_FIX, 0 },
    636 
    637 	/* Error allocating refcount structure */
    638 	{ PR_1_ALLOCATE_REFCOUNT,
    639 	  N_("@A refcount structure (%N): %m\n"),
    640 	  PROMPT_NONE, PR_FATAL },
    641 
    642 	/* Error reading extended attribute block */
    643 	{ PR_1_READ_EA_BLOCK,
    644 	  N_("Error reading @a @b %b for @i %i.  "),
    645 	  PROMPT_CLEAR, 0 },
    646 
    647 	/* Invalid extended attribute block */
    648 	{ PR_1_BAD_EA_BLOCK,
    649 	  N_("@i %i has a bad @a @b %b.  "),
    650 	  PROMPT_CLEAR, 0 },
    651 
    652 	/* Error reading Extended Attribute block while fixing refcount */
    653 	{ PR_1_EXTATTR_READ_ABORT,
    654 	  N_("Error reading @a @b %b (%m).  "),
    655 	  PROMPT_ABORT, 0 },
    656 
    657 	/* Extended attribute reference count incorrect */
    658 	{ PR_1_EXTATTR_REFCOUNT,
    659 	  N_("@a @b %b has reference count %B, @s %N.  "),
    660 	  PROMPT_FIX, 0 },
    661 
    662 	/* Error writing Extended Attribute block while fixing refcount */
    663 	{ PR_1_EXTATTR_WRITE,
    664 	  N_("Error writing @a @b %b (%m).  "),
    665 	  PROMPT_ABORT, 0 },
    666 
    667 	/* Multiple EA blocks not supported */
    668 	{ PR_1_EA_MULTI_BLOCK,
    669 	  N_("@a @b %b has h_@bs > 1.  "),
    670 	  PROMPT_CLEAR, 0},
    671 
    672 	/* Error allocating EA region allocation structure */
    673 	{ PR_1_EA_ALLOC_REGION,
    674 	  N_("@A @a @b %b.  "),
    675 	  PROMPT_ABORT, 0},
    676 
    677 	/* Error EA allocation collision */
    678 	{ PR_1_EA_ALLOC_COLLISION,
    679 	  N_("@a @b %b is corrupt (allocation collision).  "),
    680 	  PROMPT_CLEAR, 0},
    681 
    682 	/* Bad extended attribute name */
    683 	{ PR_1_EA_BAD_NAME,
    684 	  N_("@a @b %b is corrupt (@n name).  "),
    685 	  PROMPT_CLEAR, 0},
    686 
    687 	/* Bad extended attribute value */
    688 	{ PR_1_EA_BAD_VALUE,
    689 	  N_("@a @b %b is corrupt (@n value).  "),
    690 	  PROMPT_CLEAR, 0},
    691 
    692 	/* Inode too big (latch question) */
    693 	{ PR_1_INODE_TOOBIG,
    694 	  N_("@i %i is too big.  "), PROMPT_TRUNCATE, 0 },
    695 
    696 	/* Directory too big */
    697 	{ PR_1_TOOBIG_DIR,
    698 	  N_("@b #%B (%b) causes @d to be too big.  "),
    699 	  PROMPT_CLEAR, PR_LATCH_TOOBIG },
    700 
    701 	/* Regular file too big */
    702 	{ PR_1_TOOBIG_REG,
    703 	  N_("@b #%B (%b) causes file to be too big.  "),
    704 	  PROMPT_CLEAR, PR_LATCH_TOOBIG },
    705 
    706 	/* Symlink too big */
    707 	{ PR_1_TOOBIG_SYMLINK,
    708 	  N_("@b #%B (%b) causes symlink to be too big.  "),
    709 	  PROMPT_CLEAR, PR_LATCH_TOOBIG },
    710 
    711 	/* INDEX_FL flag set on a non-HTREE filesystem */
    712 	{ PR_1_HTREE_SET,
    713 	  N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
    714 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
    715 
    716 	/* INDEX_FL flag set on a non-directory */
    717 	{ PR_1_HTREE_NODIR,
    718 	  N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
    719 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
    720 
    721 	/* Invalid root node in HTREE directory */
    722 	{ PR_1_HTREE_BADROOT,
    723 	  N_("@h %i has an @n root node.\n"),
    724 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
    725 
    726 	/* Unsupported hash version in HTREE directory */
    727 	{ PR_1_HTREE_HASHV,
    728 	  N_("@h %i has an unsupported hash version (%N)\n"),
    729 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
    730 
    731 	/* Incompatible flag in HTREE root node */
    732 	{ PR_1_HTREE_INCOMPAT,
    733 	  N_("@h %i uses an incompatible htree root node flag.\n"),
    734 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
    735 
    736 	/* HTREE too deep */
    737 	{ PR_1_HTREE_DEPTH,
    738 	  N_("@h %i has a tree depth (%N) which is too big\n"),
    739 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
    740 
    741 	/* Bad block has indirect block that conflicts with filesystem block */
    742 	{ PR_1_BB_FS_BLOCK,
    743 	  N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
    744 	     "@f metadata.  "),
    745 	  PROMPT_CLEAR, PR_LATCH_BBLOCK },
    746 
    747 	/* Resize inode failed */
    748 	{ PR_1_RESIZE_INODE_CREATE,
    749 	  N_("Resize @i (re)creation failed: %m."),
    750 	  PROMPT_ABORT, 0 },
    751 
    752 	/* invalid inode->i_extra_isize */
    753 	{ PR_1_EXTRA_ISIZE,
    754 	  N_("@i %i has a extra size (%IS) which is @n\n"),
    755 	  PROMPT_FIX, PR_PREEN_OK },
    756 
    757 	/* invalid ea entry->e_name_len */
    758 	{ PR_1_ATTR_NAME_LEN,
    759 	  N_("@a in @i %i has a namelen (%N) which is @n\n"),
    760 	  PROMPT_CLEAR, PR_PREEN_OK },
    761 
    762 	/* invalid ea entry->e_value_size */
    763 	{ PR_1_ATTR_VALUE_SIZE,
    764 	  N_("@a in @i %i has a value size (%N) which is @n\n"),
    765 	  PROMPT_CLEAR, PR_PREEN_OK },
    766 
    767 	/* invalid ea entry->e_value_offs */
    768 	{ PR_1_ATTR_VALUE_OFFSET,
    769 	  N_("@a in @i %i has a value offset (%N) which is @n\n"),
    770 	  PROMPT_CLEAR, PR_PREEN_OK },
    771 
    772 	/* invalid ea entry->e_value_block */
    773 	{ PR_1_ATTR_VALUE_BLOCK,
    774 	  N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
    775 	  PROMPT_CLEAR, PR_PREEN_OK },
    776 
    777 	/* invalid ea entry->e_hash */
    778 	{ PR_1_ATTR_HASH,
    779 	  N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
    780 	  PROMPT_CLEAR, PR_PREEN_OK },
    781 
    782 	/* inode appears to be a directory */
    783 	{ PR_1_TREAT_AS_DIRECTORY,
    784 	  N_("@i %i is a %It but it looks like it is really a directory.\n"),
    785 	  PROMPT_FIX, 0 },
    786 
    787 	/* Pass 1b errors */
    788 
    789 	/* Pass 1B: Rescan for duplicate/bad blocks */
    790 	{ PR_1B_PASS_HEADER,
    791 	  N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
    792 	  "Pass 1B: Rescanning for @m @bs\n"),
    793 	  PROMPT_NONE, 0 },
    794 
    795 	/* Duplicate/bad block(s) header */
    796 	{ PR_1B_DUP_BLOCK_HEADER,
    797 	  N_("@m @b(s) in @i %i:"),
    798 	  PROMPT_NONE, 0 },
    799 
    800 	/* Duplicate/bad block(s) in inode */
    801 	{ PR_1B_DUP_BLOCK,
    802 	  " %b",
    803 	  PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
    804 
    805 	/* Duplicate/bad block(s) end */
    806 	{ PR_1B_DUP_BLOCK_END,
    807 	  "\n",
    808 	  PROMPT_NONE, PR_PREEN_NOHDR },
    809 
    810 	/* Error while scanning inodes */
    811 	{ PR_1B_ISCAN_ERROR,
    812 	  N_("Error while scanning inodes (%i): %m\n"),
    813 	  PROMPT_NONE, PR_FATAL },
    814 
    815 	/* Error allocating inode bitmap */
    816 	{ PR_1B_ALLOCATE_IBITMAP_ERROR,
    817 	  N_("@A @i @B (@i_dup_map): %m\n"),
    818 	  PROMPT_NONE, PR_FATAL },
    819 
    820 	/* Error while iterating over blocks */
    821 	{ PR_1B_BLOCK_ITERATE,
    822 	  N_("Error while iterating over @bs in @i %i (%s): %m\n"),
    823 	  PROMPT_NONE, 0 },
    824 
    825 	/* Error adjusting EA refcount */
    826 	{ PR_1B_ADJ_EA_REFCOUNT,
    827 	  N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
    828 	  PROMPT_NONE, 0 },
    829 
    830 
    831 	/* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
    832 	{ PR_1C_PASS_HEADER,
    833 	  N_("Pass 1C: Scanning directories for @is with @m @bs\n"),
    834 	  PROMPT_NONE, 0 },
    835 
    836 
    837 	/* Pass 1D: Reconciling multiply-claimed blocks */
    838 	{ PR_1D_PASS_HEADER,
    839 	  N_("Pass 1D: Reconciling @m @bs\n"),
    840 	  PROMPT_NONE, 0 },
    841 
    842 	/* File has duplicate blocks */
    843 	{ PR_1D_DUP_FILE,
    844 	  N_("File %Q (@i #%i, mod time %IM) \n"
    845 	  "  has %B @m @b(s), shared with %N file(s):\n"),
    846 	  PROMPT_NONE, 0 },
    847 
    848 	/* List of files sharing duplicate blocks */
    849 	{ PR_1D_DUP_FILE_LIST,
    850 	  N_("\t%Q (@i #%i, mod time %IM)\n"),
    851 	  PROMPT_NONE, 0 },
    852 
    853 	/* File sharing blocks with filesystem metadata  */
    854 	{ PR_1D_SHARE_METADATA,
    855 	  N_("\t<@f metadata>\n"),
    856 	  PROMPT_NONE, 0 },
    857 
    858 	/* Report of how many duplicate/bad inodes */
    859 	{ PR_1D_NUM_DUP_INODES,
    860 	  N_("(There are %N @is containing @m @bs.)\n\n"),
    861 	  PROMPT_NONE, 0 },
    862 
    863 	/* Duplicated blocks already reassigned or cloned. */
    864 	{ PR_1D_DUP_BLOCKS_DEALT,
    865 	  N_("@m @bs already reassigned or cloned.\n\n"),
    866 	  PROMPT_NONE, 0 },
    867 
    868 	/* Clone duplicate/bad blocks? */
    869 	{ PR_1D_CLONE_QUESTION,
    870 	  "", PROMPT_CLONE, PR_NO_OK },
    871 
    872 	/* Delete file? */
    873 	{ PR_1D_DELETE_QUESTION,
    874 	  "", PROMPT_DELETE, 0 },
    875 
    876 	/* Couldn't clone file (error) */
    877 	{ PR_1D_CLONE_ERROR,
    878 	  N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
    879 
    880 	/* Pass 2 errors */
    881 
    882 	/* Pass 2: Checking directory structure */
    883 	{ PR_2_PASS_HEADER,
    884 	  N_("Pass 2: Checking @d structure\n"),
    885 	  PROMPT_NONE, 0 },
    886 
    887 	/* Bad inode number for '.' */
    888 	{ PR_2_BAD_INODE_DOT,
    889 	  N_("@n @i number for '.' in @d @i %i.\n"),
    890 	  PROMPT_FIX, 0 },
    891 
    892 	/* Directory entry has bad inode number */
    893 	{ PR_2_BAD_INO,
    894 	  N_("@E has @n @i #: %Di.\n"),
    895 	  PROMPT_CLEAR, 0 },
    896 
    897 	/* Directory entry has deleted or unused inode */
    898 	{ PR_2_UNUSED_INODE,
    899 	  N_("@E has @D/unused @i %Di.  "),
    900 	  PROMPT_CLEAR, PR_PREEN_OK },
    901 
    902 	/* Directry entry is link to '.' */
    903 	{ PR_2_LINK_DOT,
    904 	  N_("@E @L to '.'  "),
    905 	  PROMPT_CLEAR, 0 },
    906 
    907 	/* Directory entry points to inode now located in a bad block */
    908 	{ PR_2_BB_INODE,
    909 	  N_("@E points to @i (%Di) located in a bad @b.\n"),
    910 	  PROMPT_CLEAR, 0 },
    911 
    912 	/* Directory entry contains a link to a directory */
    913 	{ PR_2_LINK_DIR,
    914 	  N_("@E @L to @d %P (%Di).\n"),
    915 	  PROMPT_CLEAR, 0 },
    916 
    917 	/* Directory entry contains a link to the root directry */
    918 	{ PR_2_LINK_ROOT,
    919 	  N_("@E @L to the @r.\n"),
    920 	  PROMPT_CLEAR, 0 },
    921 
    922 	/* Directory entry has illegal characters in its name */
    923 	{ PR_2_BAD_NAME,
    924 	  N_("@E has illegal characters in its name.\n"),
    925 	  PROMPT_FIX, 0 },
    926 
    927 	/* Missing '.' in directory inode */
    928 	{ PR_2_MISSING_DOT,
    929 	  N_("Missing '.' in @d @i %i.\n"),
    930 	  PROMPT_FIX, 0 },
    931 
    932 	/* Missing '..' in directory inode */
    933 	{ PR_2_MISSING_DOT_DOT,
    934 	  N_("Missing '..' in @d @i %i.\n"),
    935 	  PROMPT_FIX, 0 },
    936 
    937 	/* First entry in directory inode doesn't contain '.' */
    938 	{ PR_2_1ST_NOT_DOT,
    939 	  N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
    940 	  PROMPT_FIX, 0 },
    941 
    942 	/* Second entry in directory inode doesn't contain '..' */
    943 	{ PR_2_2ND_NOT_DOT_DOT,
    944 	  N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
    945 	  PROMPT_FIX, 0 },
    946 
    947 	/* i_faddr should be zero */
    948 	{ PR_2_FADDR_ZERO,
    949 	  N_("i_faddr @F %IF, @s zero.\n"),
    950 	  PROMPT_CLEAR, 0 },
    951 
    952   	/* i_file_acl should be zero */
    953 	{ PR_2_FILE_ACL_ZERO,
    954 	  N_("i_file_acl @F %If, @s zero.\n"),
    955 	  PROMPT_CLEAR, 0 },
    956 
    957   	/* i_dir_acl should be zero */
    958 	{ PR_2_DIR_ACL_ZERO,
    959 	  N_("i_dir_acl @F %Id, @s zero.\n"),
    960 	  PROMPT_CLEAR, 0 },
    961 
    962   	/* i_frag should be zero */
    963 	{ PR_2_FRAG_ZERO,
    964 	  N_("i_frag @F %N, @s zero.\n"),
    965 	  PROMPT_CLEAR, 0 },
    966 
    967   	/* i_fsize should be zero */
    968 	{ PR_2_FSIZE_ZERO,
    969 	  N_("i_fsize @F %N, @s zero.\n"),
    970 	  PROMPT_CLEAR, 0 },
    971 
    972 	/* inode has bad mode */
    973 	{ PR_2_BAD_MODE,
    974 	  N_("@i %i (%Q) has @n mode (%Im).\n"),
    975 	  PROMPT_CLEAR, 0 },
    976 
    977 	/* directory corrupted */
    978 	{ PR_2_DIR_CORRUPTED,
    979 	  N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
    980 	  PROMPT_SALVAGE, 0 },
    981 
    982 	/* filename too long */
    983 	{ PR_2_FILENAME_LONG,
    984 	  N_("@d @i %i, @b %B, offset %N: filename too long\n"),
    985 	  PROMPT_TRUNCATE, 0 },
    986 
    987 	/* Directory inode has a missing block (hole) */
    988 	{ PR_2_DIRECTORY_HOLE,
    989 	  N_("@d @i %i has an unallocated @b #%B.  "),
    990 	  PROMPT_ALLOCATE, 0 },
    991 
    992 	/* '.' is not NULL terminated */
    993 	{ PR_2_DOT_NULL_TERM,
    994 	  N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
    995 	  PROMPT_FIX, 0 },
    996 
    997 	/* '..' is not NULL terminated */
    998 	{ PR_2_DOT_DOT_NULL_TERM,
    999 	  N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
   1000 	  PROMPT_FIX, 0 },
   1001 
   1002 	/* Illegal character device inode */
   1003 	{ PR_2_BAD_CHAR_DEV,
   1004 	  N_("@i %i (%Q) is an @I character @v.\n"),
   1005 	  PROMPT_CLEAR, 0 },
   1006 
   1007 	/* Illegal block device inode */
   1008 	{ PR_2_BAD_BLOCK_DEV,
   1009 	  N_("@i %i (%Q) is an @I @b @v.\n"),
   1010 	  PROMPT_CLEAR, 0 },
   1011 
   1012 	/* Duplicate '.' entry */
   1013 	{ PR_2_DUP_DOT,
   1014 	  N_("@E is duplicate '.' @e.\n"),
   1015 	  PROMPT_FIX, 0 },
   1016 
   1017 	/* Duplicate '..' entry */
   1018 	{ PR_2_DUP_DOT_DOT,
   1019 	  N_("@E is duplicate '..' @e.\n"),
   1020 	  PROMPT_FIX, 0 },
   1021 
   1022 	/* Internal error: couldn't find dir_info */
   1023 	{ PR_2_NO_DIRINFO,
   1024 	  N_("Internal error: couldn't find dir_info for %i.\n"),
   1025 	  PROMPT_NONE, PR_FATAL },
   1026 
   1027 	/* Final rec_len is wrong */
   1028 	{ PR_2_FINAL_RECLEN,
   1029 	  N_("@E has rec_len of %Dr, @s %N.\n"),
   1030 	  PROMPT_FIX, 0 },
   1031 
   1032 	/* Error allocating icount structure */
   1033 	{ PR_2_ALLOCATE_ICOUNT,
   1034 	  N_("@A icount structure: %m\n"),
   1035 	  PROMPT_NONE, PR_FATAL },
   1036 
   1037 	/* Error iterating over directory blocks */
   1038 	{ PR_2_DBLIST_ITERATE,
   1039 	  N_("Error iterating over @d @bs: %m\n"),
   1040 	  PROMPT_NONE, PR_FATAL },
   1041 
   1042 	/* Error reading directory block */
   1043 	{ PR_2_READ_DIRBLOCK,
   1044 	  N_("Error reading @d @b %b (@i %i): %m\n"),
   1045 	  PROMPT_CONTINUE, 0 },
   1046 
   1047 	/* Error writing directory block */
   1048 	{ PR_2_WRITE_DIRBLOCK,
   1049 	  N_("Error writing @d @b %b (@i %i): %m\n"),
   1050 	  PROMPT_CONTINUE, 0 },
   1051 
   1052 	/* Error allocating new directory block */
   1053 	{ PR_2_ALLOC_DIRBOCK,
   1054 	  N_("@A new @d @b for @i %i (%s): %m\n"),
   1055 	  PROMPT_NONE, 0 },
   1056 
   1057 	/* Error deallocating inode */
   1058 	{ PR_2_DEALLOC_INODE,
   1059 	  N_("Error deallocating @i %i: %m\n"),
   1060 	  PROMPT_NONE, PR_FATAL },
   1061 
   1062 	/* Directory entry for '.' is big.  Split? */
   1063 	{ PR_2_SPLIT_DOT,
   1064 	  N_("@d @e for '.' is big.  "),
   1065 	  PROMPT_SPLIT, PR_NO_OK },
   1066 
   1067 	/* Illegal FIFO inode */
   1068 	{ PR_2_BAD_FIFO,
   1069 	  N_("@i %i (%Q) is an @I FIFO.\n"),
   1070 	  PROMPT_CLEAR, 0 },
   1071 
   1072 	/* Illegal socket inode */
   1073 	{ PR_2_BAD_SOCKET,
   1074 	  N_("@i %i (%Q) is an @I socket.\n"),
   1075 	  PROMPT_CLEAR, 0 },
   1076 
   1077 	/* Directory filetype not set */
   1078 	{ PR_2_SET_FILETYPE,
   1079 	  N_("Setting filetype for @E to %N.\n"),
   1080 	  PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
   1081 
   1082 	/* Directory filetype incorrect */
   1083 	{ PR_2_BAD_FILETYPE,
   1084 	  N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
   1085 	  PROMPT_FIX, 0 },
   1086 
   1087 	/* Directory filetype set on filesystem */
   1088 	{ PR_2_CLEAR_FILETYPE,
   1089 	  N_("@E has filetype set.\n"),
   1090 	  PROMPT_CLEAR, PR_PREEN_OK },
   1091 
   1092 	/* Directory filename is null */
   1093 	{ PR_2_NULL_NAME,
   1094 	  N_("@E has a @z name.\n"),
   1095 	  PROMPT_CLEAR, 0 },
   1096 
   1097 	/* Invalid symlink */
   1098 	{ PR_2_INVALID_SYMLINK,
   1099 	  N_("Symlink %Q (@i #%i) is @n.\n"),
   1100 	  PROMPT_CLEAR, 0 },
   1101 
   1102   	/* i_file_acl (extended attribute block) is bad */
   1103 	{ PR_2_FILE_ACL_BAD,
   1104 	  N_("@a @b @F @n (%If).\n"),
   1105 	  PROMPT_CLEAR, 0 },
   1106 
   1107 	/* Filesystem contains large files, but has no such flag in sb */
   1108 	{ PR_2_FEATURE_LARGE_FILES,
   1109 	  N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
   1110 	  PROMPT_FIX, 0 },
   1111 
   1112 	/* Node in HTREE directory not referenced */
   1113 	{ PR_2_HTREE_NOTREF,
   1114 	  N_("@p @h %d: node (%B) not referenced\n"),
   1115 	  PROMPT_NONE, 0 },
   1116 
   1117 	/* Node in HTREE directory referenced twice */
   1118 	{ PR_2_HTREE_DUPREF,
   1119 	  N_("@p @h %d: node (%B) referenced twice\n"),
   1120 	  PROMPT_NONE, 0 },
   1121 
   1122 	/* Node in HTREE directory has bad min hash */
   1123 	{ PR_2_HTREE_MIN_HASH,
   1124 	  N_("@p @h %d: node (%B) has bad min hash\n"),
   1125 	  PROMPT_NONE, 0 },
   1126 
   1127 	/* Node in HTREE directory has bad max hash */
   1128 	{ PR_2_HTREE_MAX_HASH,
   1129 	  N_("@p @h %d: node (%B) has bad max hash\n"),
   1130 	  PROMPT_NONE, 0 },
   1131 
   1132 	/* Clear invalid HTREE directory */
   1133 	{ PR_2_HTREE_CLEAR,
   1134 	  N_("@n @h %d (%q).  "), PROMPT_CLEAR_HTREE, 0 },
   1135 
   1136 	/* Bad block in htree interior node */
   1137 	{ PR_2_HTREE_BADBLK,
   1138 	  N_("@p @h %d (%q): bad @b number %b.\n"),
   1139 	  PROMPT_CLEAR_HTREE, 0 },
   1140 
   1141 	/* Error adjusting EA refcount */
   1142 	{ PR_2_ADJ_EA_REFCOUNT,
   1143 	  N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
   1144 	  PROMPT_NONE, PR_FATAL },
   1145 
   1146 	/* Invalid HTREE root node */
   1147 	{ PR_2_HTREE_BAD_ROOT,
   1148 	  N_("@p @h %d: root node is @n\n"),
   1149 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
   1150 
   1151 	/* Invalid HTREE limit */
   1152 	{ PR_2_HTREE_BAD_LIMIT,
   1153 	  N_("@p @h %d: node (%B) has @n limit (%N)\n"),
   1154 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
   1155 
   1156 	/* Invalid HTREE count */
   1157 	{ PR_2_HTREE_BAD_COUNT,
   1158 	  N_("@p @h %d: node (%B) has @n count (%N)\n"),
   1159 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
   1160 
   1161 	/* HTREE interior node has out-of-order hashes in table */
   1162 	{ PR_2_HTREE_HASH_ORDER,
   1163 	  N_("@p @h %d: node (%B) has an unordered hash table\n"),
   1164 	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
   1165 
   1166 	/* Node in HTREE directory has invalid depth */
   1167 	{ PR_2_HTREE_BAD_DEPTH,
   1168 	  N_("@p @h %d: node (%B) has @n depth\n"),
   1169 	  PROMPT_NONE, 0 },
   1170 
   1171 	/* Duplicate directory entry found */
   1172 	{ PR_2_DUPLICATE_DIRENT,
   1173 	  N_("Duplicate @E found.  "),
   1174 	  PROMPT_CLEAR, 0 },
   1175 
   1176 	/* Non-unique filename found */
   1177 	{ PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
   1178 	  N_("@E has a non-unique filename.\nRename to %s"),
   1179 	  PROMPT_NULL, 0 },
   1180 
   1181 	/* Duplicate directory entry found */
   1182 	{ PR_2_REPORT_DUP_DIRENT,
   1183 	  N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
   1184 	  PROMPT_NONE, 0 },
   1185 
   1186   	/* i_blocks_hi should be zero */
   1187 	{ PR_2_BLOCKS_HI_ZERO,
   1188 	  N_("i_blocks_hi @F %N, @s zero.\n"),
   1189 	  PROMPT_CLEAR, 0 },
   1190 
   1191 	/* Unexpected HTREE block */
   1192 	{ PR_2_UNEXPECTED_HTREE_BLOCK,
   1193 	  N_("Unexpected @b in @h %d (%q).\n"), PROMPT_CLEAR_HTREE, 0 },
   1194 
   1195 	/* Pass 3 errors */
   1196 
   1197 	/* Pass 3: Checking directory connectivity */
   1198 	{ PR_3_PASS_HEADER,
   1199 	  N_("Pass 3: Checking @d connectivity\n"),
   1200 	  PROMPT_NONE, 0 },
   1201 
   1202 	/* Root inode not allocated */
   1203 	{ PR_3_NO_ROOT_INODE,
   1204 	  N_("@r not allocated.  "),
   1205 	  PROMPT_ALLOCATE, 0 },
   1206 
   1207 	/* No room in lost+found */
   1208 	{ PR_3_EXPAND_LF_DIR,
   1209 	  N_("No room in @l @d.  "),
   1210 	  PROMPT_EXPAND, 0 },
   1211 
   1212 	/* Unconnected directory inode */
   1213 	{ PR_3_UNCONNECTED_DIR,
   1214 	  N_("Unconnected @d @i %i (%p)\n"),
   1215 	  PROMPT_CONNECT, 0 },
   1216 
   1217 	/* /lost+found not found */
   1218 	{ PR_3_NO_LF_DIR,
   1219 	  N_("/@l not found.  "),
   1220 	  PROMPT_CREATE, PR_PREEN_OK },
   1221 
   1222 	/* .. entry is incorrect */
   1223 	{ PR_3_BAD_DOT_DOT,
   1224 	  N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
   1225 	  PROMPT_FIX, 0 },
   1226 
   1227 	/* Bad or non-existent /lost+found.  Cannot reconnect */
   1228 	{ PR_3_NO_LPF,
   1229 	  N_("Bad or non-existent /@l.  Cannot reconnect.\n"),
   1230 	  PROMPT_NONE, 0 },
   1231 
   1232 	/* Could not expand /lost+found */
   1233 	{ PR_3_CANT_EXPAND_LPF,
   1234 	  N_("Could not expand /@l: %m\n"),
   1235 	  PROMPT_NONE, 0 },
   1236 
   1237 	/* Could not reconnect inode */
   1238 	{ PR_3_CANT_RECONNECT,
   1239 	  N_("Could not reconnect %i: %m\n"),
   1240 	  PROMPT_NONE, 0 },
   1241 
   1242 	/* Error while trying to find /lost+found */
   1243 	{ PR_3_ERR_FIND_LPF,
   1244 	  N_("Error while trying to find /@l: %m\n"),
   1245 	  PROMPT_NONE, 0 },
   1246 
   1247 	/* Error in ext2fs_new_block while creating /lost+found */
   1248 	{ PR_3_ERR_LPF_NEW_BLOCK,
   1249 	  N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
   1250 	  PROMPT_NONE, 0 },
   1251 
   1252 	/* Error in ext2fs_new_inode while creating /lost+found */
   1253 	{ PR_3_ERR_LPF_NEW_INODE,
   1254 	  N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
   1255 	  PROMPT_NONE, 0 },
   1256 
   1257 	/* Error in ext2fs_new_dir_block while creating /lost+found */
   1258 	{ PR_3_ERR_LPF_NEW_DIR_BLOCK,
   1259 	  N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
   1260 	  PROMPT_NONE, 0 },
   1261 
   1262 	/* Error while writing directory block for /lost+found */
   1263 	{ PR_3_ERR_LPF_WRITE_BLOCK,
   1264 	  N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
   1265 	  PROMPT_NONE, 0 },
   1266 
   1267 	/* Error while adjusting inode count */
   1268 	{ PR_3_ADJUST_INODE,
   1269 	  N_("Error while adjusting @i count on @i %i\n"),
   1270 	  PROMPT_NONE, 0 },
   1271 
   1272 	/* Couldn't fix parent directory -- error */
   1273 	{ PR_3_FIX_PARENT_ERR,
   1274 	  N_("Couldn't fix parent of @i %i: %m\n\n"),
   1275 	  PROMPT_NONE, 0 },
   1276 
   1277 	/* Couldn't fix parent directory -- couldn't find it */
   1278 	{ PR_3_FIX_PARENT_NOFIND,
   1279 	  N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
   1280 	  PROMPT_NONE, 0 },
   1281 
   1282 	/* Error allocating inode bitmap */
   1283 	{ PR_3_ALLOCATE_IBITMAP_ERROR,
   1284 	  N_("@A @i @B (%N): %m\n"),
   1285 	  PROMPT_NONE, PR_FATAL },
   1286 
   1287 	/* Error creating root directory */
   1288 	{ PR_3_CREATE_ROOT_ERROR,
   1289 	  N_("Error creating root @d (%s): %m\n"),
   1290 	  PROMPT_NONE, PR_FATAL },
   1291 
   1292 	/* Error creating lost and found directory */
   1293 	{ PR_3_CREATE_LPF_ERROR,
   1294 	  N_("Error creating /@l @d (%s): %m\n"),
   1295 	  PROMPT_NONE, PR_FATAL },
   1296 
   1297 	/* Root inode is not directory; aborting */
   1298 	{ PR_3_ROOT_NOT_DIR_ABORT,
   1299 	  N_("@r is not a @d; aborting.\n"),
   1300 	  PROMPT_NONE, PR_FATAL },
   1301 
   1302 	/* Cannot proceed without a root inode. */
   1303 	{ PR_3_NO_ROOT_INODE_ABORT,
   1304 	  N_("Cannot proceed without a @r.\n"),
   1305 	  PROMPT_NONE, PR_FATAL },
   1306 
   1307 	/* Internal error: couldn't find dir_info */
   1308 	{ PR_3_NO_DIRINFO,
   1309 	  N_("Internal error: couldn't find dir_info for %i.\n"),
   1310 	  PROMPT_NONE, PR_FATAL },
   1311 
   1312 	/* Lost+found not a directory */
   1313 	{ PR_3_LPF_NOTDIR,
   1314 	  N_("/@l is not a @d (ino=%i)\n"),
   1315 	  PROMPT_UNLINK, 0 },
   1316 
   1317 	/* Pass 3A Directory Optimization	*/
   1318 
   1319 	/* Pass 3A: Optimizing directories */
   1320 	{ PR_3A_PASS_HEADER,
   1321 	  N_("Pass 3A: Optimizing directories\n"),
   1322 	  PROMPT_NONE, PR_PREEN_NOMSG },
   1323 
   1324 	/* Error iterating over directories */
   1325 	{ PR_3A_OPTIMIZE_ITER,
   1326 	  N_("Failed to create dirs_to_hash iterator: %m"),
   1327 	  PROMPT_NONE, 0 },
   1328 
   1329 	/* Error rehash directory */
   1330 	{ PR_3A_OPTIMIZE_DIR_ERR,
   1331 	  N_("Failed to optimize directory %q (%d): %m"),
   1332 	  PROMPT_NONE, 0 },
   1333 
   1334 	/* Rehashing dir header */
   1335 	{ PR_3A_OPTIMIZE_DIR_HEADER,
   1336 	  N_("Optimizing directories: "),
   1337 	  PROMPT_NONE, PR_MSG_ONLY },
   1338 
   1339 	/* Rehashing directory %d */
   1340 	{ PR_3A_OPTIMIZE_DIR,
   1341 	  " %d",
   1342 	  PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
   1343 
   1344 	/* Rehashing dir end */
   1345 	{ PR_3A_OPTIMIZE_DIR_END,
   1346 	  "\n",
   1347 	  PROMPT_NONE, PR_PREEN_NOHDR },
   1348 
   1349 	/* Pass 4 errors */
   1350 
   1351 	/* Pass 4: Checking reference counts */
   1352 	{ PR_4_PASS_HEADER,
   1353 	  N_("Pass 4: Checking reference counts\n"),
   1354 	  PROMPT_NONE, 0 },
   1355 
   1356 	/* Unattached zero-length inode */
   1357 	{ PR_4_ZERO_LEN_INODE,
   1358 	  N_("@u @z @i %i.  "),
   1359 	  PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
   1360 
   1361 	/* Unattached inode */
   1362 	{ PR_4_UNATTACHED_INODE,
   1363 	  N_("@u @i %i\n"),
   1364 	  PROMPT_CONNECT, 0 },
   1365 
   1366 	/* Inode ref count wrong */
   1367 	{ PR_4_BAD_REF_COUNT,
   1368 	  N_("@i %i ref count is %Il, @s %N.  "),
   1369 	  PROMPT_FIX, PR_PREEN_OK },
   1370 
   1371 	{ PR_4_INCONSISTENT_COUNT,
   1372 	  N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
   1373 	  "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
   1374 	  "@i_link_info[%i] is %N, @i.i_links_count is %Il.  "
   1375 	  "They @s the same!\n"),
   1376 	  PROMPT_NONE, 0 },
   1377 
   1378 	/* Pass 5 errors */
   1379 
   1380 	/* Pass 5: Checking group summary information */
   1381 	{ PR_5_PASS_HEADER,
   1382 	  N_("Pass 5: Checking @g summary information\n"),
   1383 	  PROMPT_NONE, 0 },
   1384 
   1385 	/* Padding at end of inode bitmap is not set. */
   1386 	{ PR_5_INODE_BMAP_PADDING,
   1387 	  N_("Padding at end of @i @B is not set. "),
   1388 	  PROMPT_FIX, PR_PREEN_OK },
   1389 
   1390 	/* Padding at end of block bitmap is not set. */
   1391 	{ PR_5_BLOCK_BMAP_PADDING,
   1392 	  N_("Padding at end of @b @B is not set. "),
   1393 	  PROMPT_FIX, PR_PREEN_OK },
   1394 
   1395 	/* Block bitmap differences header */
   1396 	{ PR_5_BLOCK_BITMAP_HEADER,
   1397 	  N_("@b @B differences: "),
   1398 	  PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
   1399 
   1400 	/* Block not used, but marked in bitmap */
   1401 	{ PR_5_BLOCK_UNUSED,
   1402 	  " -%b",
   1403 	  PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1404 
   1405 	/* Block used, but not marked used in bitmap */
   1406 	{ PR_5_BLOCK_USED,
   1407 	  " +%b",
   1408 	  PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1409 
   1410 	/* Block bitmap differences end */
   1411 	{ PR_5_BLOCK_BITMAP_END,
   1412 	  "\n",
   1413 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1414 
   1415 	/* Inode bitmap differences header */
   1416 	{ PR_5_INODE_BITMAP_HEADER,
   1417 	  N_("@i @B differences: "),
   1418 	  PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
   1419 
   1420 	/* Inode not used, but marked in bitmap */
   1421 	{ PR_5_INODE_UNUSED,
   1422 	  " -%i",
   1423 	  PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1424 
   1425 	/* Inode used, but not marked used in bitmap */
   1426 	{ PR_5_INODE_USED,
   1427 	  " +%i",
   1428 	  PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1429 
   1430 	/* Inode bitmap differences end */
   1431 	{ PR_5_INODE_BITMAP_END,
   1432 	  "\n",
   1433 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1434 
   1435 	/* Free inodes count for group wrong */
   1436 	{ PR_5_FREE_INODE_COUNT_GROUP,
   1437 	  N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
   1438 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1439 
   1440 	/* Directories count for group wrong */
   1441 	{ PR_5_FREE_DIR_COUNT_GROUP,
   1442 	  N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
   1443 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1444 
   1445 	/* Free inodes count wrong */
   1446 	{ PR_5_FREE_INODE_COUNT,
   1447 	  N_("Free @is count wrong (%i, counted=%j).\n"),
   1448 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1449 
   1450 	/* Free blocks count for group wrong */
   1451 	{ PR_5_FREE_BLOCK_COUNT_GROUP,
   1452 	  N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
   1453 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1454 
   1455 	/* Free blocks count wrong */
   1456 	{ PR_5_FREE_BLOCK_COUNT,
   1457 	  N_("Free @bs count wrong (%b, counted=%c).\n"),
   1458 	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
   1459 
   1460 	/* Programming error: bitmap endpoints don't match */
   1461 	{ PR_5_BMAP_ENDPOINTS,
   1462 	  N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
   1463 	  "match calculated @B endpoints (%i, %j)\n"),
   1464 	  PROMPT_NONE, PR_FATAL },
   1465 
   1466 	/* Internal error: fudging end of bitmap */
   1467 	{ PR_5_FUDGE_BITMAP_ERROR,
   1468 	  N_("Internal error: fudging end of bitmap (%N)\n"),
   1469 	  PROMPT_NONE, PR_FATAL },
   1470 
   1471 	/* Error copying in replacement inode bitmap */
   1472 	{ PR_5_COPY_IBITMAP_ERROR,
   1473 	  N_("Error copying in replacement @i @B: %m\n"),
   1474 	  PROMPT_NONE, PR_FATAL },
   1475 
   1476 	/* Error copying in replacement block bitmap */
   1477 	{ PR_5_COPY_BBITMAP_ERROR,
   1478 	  N_("Error copying in replacement @b @B: %m\n"),
   1479 	  PROMPT_NONE, PR_FATAL },
   1480 
   1481 	/* Block range not used, but marked in bitmap */
   1482 	{ PR_5_BLOCK_RANGE_UNUSED,
   1483 	  " -(%b--%c)",
   1484 	  PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1485 
   1486 	/* Block range used, but not marked used in bitmap */
   1487 	{ PR_5_BLOCK_RANGE_USED,
   1488 	  " +(%b--%c)",
   1489 	  PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1490 
   1491 	/* Inode range not used, but marked in bitmap */
   1492 	{ PR_5_INODE_RANGE_UNUSED,
   1493 	  " -(%i--%j)",
   1494 	  PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1495 
   1496 	/* Inode range used, but not marked used in bitmap */
   1497 	{ PR_5_INODE_RANGE_USED,
   1498 	  " +(%i--%j)",
   1499 	  PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
   1500 
   1501 	/* Recreate journal if E2F_FLAG_JOURNAL_INODE flag is set */
   1502 	{ PR_6_RECREATE_JOURNAL,
   1503 	  N_("Recreate journal to make the filesystem ext3 again?\n"),
   1504 	  PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
   1505 
   1506 	{ 0 }
   1507 };
   1508 
   1509 /*
   1510  * This is the latch flags register.  It allows several problems to be
   1511  * "latched" together.  This means that the user has to answer but one
   1512  * question for the set of problems, and all of the associated
   1513  * problems will be either fixed or not fixed.
   1514  */
   1515 static struct latch_descr pr_latch_info[] = {
   1516 	{ PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
   1517 	{ PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
   1518 	{ PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
   1519 	{ PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
   1520 	{ PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
   1521 	{ PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
   1522 	{ PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
   1523 	{ PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
   1524 	{ PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
   1525 	{ -1, 0, 0 },
   1526 };
   1527 
   1528 static struct e2fsck_problem *find_problem(problem_t code)
   1529 {
   1530 	int 	i;
   1531 
   1532 	for (i=0; problem_table[i].e2p_code; i++) {
   1533 		if (problem_table[i].e2p_code == code)
   1534 			return &problem_table[i];
   1535 	}
   1536 	return 0;
   1537 }
   1538 
   1539 static struct latch_descr *find_latch(int code)
   1540 {
   1541 	int	i;
   1542 
   1543 	for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
   1544 		if (pr_latch_info[i].latch_code == code)
   1545 			return &pr_latch_info[i];
   1546 	}
   1547 	return 0;
   1548 }
   1549 
   1550 int end_problem_latch(e2fsck_t ctx, int mask)
   1551 {
   1552 	struct latch_descr *ldesc;
   1553 	struct problem_context pctx;
   1554 	int answer = -1;
   1555 
   1556 	ldesc = find_latch(mask);
   1557 	if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
   1558 		clear_problem_context(&pctx);
   1559 		answer = fix_problem(ctx, ldesc->end_message, &pctx);
   1560 	}
   1561 	ldesc->flags &= ~(PRL_VARIABLE);
   1562 	return answer;
   1563 }
   1564 
   1565 int set_latch_flags(int mask, int setflags, int clearflags)
   1566 {
   1567 	struct latch_descr *ldesc;
   1568 
   1569 	ldesc = find_latch(mask);
   1570 	if (!ldesc)
   1571 		return -1;
   1572 	ldesc->flags |= setflags;
   1573 	ldesc->flags &= ~clearflags;
   1574 	return 0;
   1575 }
   1576 
   1577 int get_latch_flags(int mask, int *value)
   1578 {
   1579 	struct latch_descr *ldesc;
   1580 
   1581 	ldesc = find_latch(mask);
   1582 	if (!ldesc)
   1583 		return -1;
   1584 	*value = ldesc->flags;
   1585 	return 0;
   1586 }
   1587 
   1588 void clear_problem_context(struct problem_context *ctx)
   1589 {
   1590 	memset(ctx, 0, sizeof(struct problem_context));
   1591 	ctx->blkcount = -1;
   1592 	ctx->group = -1;
   1593 }
   1594 
   1595 static void reconfigure_bool(e2fsck_t ctx, struct e2fsck_problem *ptr,
   1596 			     const char *key, int mask, const char *name)
   1597 {
   1598 	int	bool;
   1599 
   1600 	bool = (ptr->flags & mask);
   1601 	profile_get_boolean(ctx->profile, "problems", key, name, bool, &bool);
   1602 	if (bool)
   1603 		ptr->flags |= mask;
   1604 	else
   1605 		ptr->flags &= ~mask;
   1606 }
   1607 
   1608 
   1609 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
   1610 {
   1611 	ext2_filsys fs = ctx->fs;
   1612 	struct e2fsck_problem *ptr;
   1613 	struct latch_descr *ldesc = 0;
   1614 	const char *message;
   1615 	int 		def_yn, answer, ans;
   1616 	int		print_answer = 0;
   1617 	int		suppress = 0;
   1618 
   1619 	ptr = find_problem(code);
   1620 	if (!ptr) {
   1621 		printf(_("Unhandled error code (0x%x)!\n"), code);
   1622 		return 0;
   1623 	}
   1624 	if (!(ptr->flags & PR_CONFIG)) {
   1625 		char	key[9], *new_desc;
   1626 
   1627 		sprintf(key, "0x%06x", code);
   1628 
   1629 		profile_get_string(ctx->profile, "problems", key,
   1630 				   "description", 0, &new_desc);
   1631 		if (new_desc)
   1632 			ptr->e2p_description = new_desc;
   1633 
   1634 		reconfigure_bool(ctx, ptr, key, PR_PREEN_OK, "preen_ok");
   1635 		reconfigure_bool(ctx, ptr, key, PR_NO_OK, "no_ok");
   1636 		reconfigure_bool(ctx, ptr, key, PR_NO_DEFAULT, "no_default");
   1637 		reconfigure_bool(ctx, ptr, key, PR_MSG_ONLY, "print_message_only");
   1638 		reconfigure_bool(ctx, ptr, key, PR_PREEN_NOMSG, "preen_nomessage");
   1639 		reconfigure_bool(ctx, ptr, key, PR_NOCOLLATE, "no_collate");
   1640 		reconfigure_bool(ctx, ptr, key, PR_NO_NOMSG, "no_nomsg");
   1641 		reconfigure_bool(ctx, ptr, key, PR_PREEN_NOHDR, "preen_noheader");
   1642 
   1643 		ptr->flags |= PR_CONFIG;
   1644 	}
   1645 	def_yn = 1;
   1646 	if ((ptr->flags & PR_NO_DEFAULT) ||
   1647 	    ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
   1648 	    (ctx->options & E2F_OPT_NO))
   1649 		def_yn= 0;
   1650 
   1651 	/*
   1652 	 * Do special latch processing.  This is where we ask the
   1653 	 * latch question, if it exists
   1654 	 */
   1655 	if (ptr->flags & PR_LATCH_MASK) {
   1656 		ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
   1657 		if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
   1658 			ans = fix_problem(ctx, ldesc->question, pctx);
   1659 			if (ans == 1)
   1660 				ldesc->flags |= PRL_YES;
   1661 			if (ans == 0)
   1662 				ldesc->flags |= PRL_NO;
   1663 			ldesc->flags |= PRL_LATCHED;
   1664 		}
   1665 		if (ldesc->flags & PRL_SUPPRESS)
   1666 			suppress++;
   1667 	}
   1668 	if ((ptr->flags & PR_PREEN_NOMSG) &&
   1669 	    (ctx->options & E2F_OPT_PREEN))
   1670 		suppress++;
   1671 	if ((ptr->flags & PR_NO_NOMSG) &&
   1672 	    (ctx->options & E2F_OPT_NO))
   1673 		suppress++;
   1674 	if (!suppress) {
   1675 		message = ptr->e2p_description;
   1676 		if ((ctx->options & E2F_OPT_PREEN) &&
   1677 		    !(ptr->flags & PR_PREEN_NOHDR)) {
   1678 			printf("%s: ", ctx->device_name ?
   1679 			       ctx->device_name : ctx->filesystem_name);
   1680 		}
   1681 		if (*message)
   1682 			print_e2fsck_message(ctx, _(message), pctx, 1, 0);
   1683 	}
   1684 	if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
   1685 		preenhalt(ctx);
   1686 
   1687 	if (ptr->flags & PR_FATAL)
   1688 		fatal_error(ctx, 0);
   1689 
   1690 	if (ptr->prompt == PROMPT_NONE) {
   1691 		if (ptr->flags & PR_NOCOLLATE)
   1692 			answer = -1;
   1693 		else
   1694 			answer = def_yn;
   1695 	} else {
   1696 		if (ctx->options & E2F_OPT_PREEN) {
   1697 			answer = def_yn;
   1698 			if (!(ptr->flags & PR_PREEN_NOMSG))
   1699 				print_answer = 1;
   1700 		} else if ((ptr->flags & PR_LATCH_MASK) &&
   1701 			   (ldesc->flags & (PRL_YES | PRL_NO))) {
   1702 			if (!suppress)
   1703 				print_answer = 1;
   1704 			if (ldesc->flags & PRL_YES)
   1705 				answer = 1;
   1706 			else
   1707 				answer = 0;
   1708 		} else
   1709 			answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
   1710 		if (!answer && !(ptr->flags & PR_NO_OK))
   1711 			ext2fs_unmark_valid(fs);
   1712 
   1713 		if (print_answer)
   1714 			printf("%s.\n", answer ?
   1715 			       _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
   1716 
   1717 	}
   1718 
   1719 	if ((ptr->prompt == PROMPT_ABORT) && answer)
   1720 		fatal_error(ctx, 0);
   1721 
   1722 	if (ptr->flags & PR_AFTER_CODE)
   1723 		answer = fix_problem(ctx, ptr->second_code, pctx);
   1724 
   1725 	return answer;
   1726 }
   1727