2 * problem.c --- report filesystem problems to the user
4 * Copyright 1996, 1997 by Theodore Ts'o
7 * This file may be redistributed under the terms of the GNU Public
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
43 * These are the prompts which are used to ask the user if they want
46 static const char *prompt[] = {
47 N_("(no prompt)"), /* 0 */
50 N_("Relocate"), /* 3 */
51 N_("Allocate"), /* 4 */
53 N_("Connect to /lost+found"), /* 6 */
55 N_("Salvage"), /* 8 */
56 N_("Truncate"), /* 9 */
57 N_("Clear inode"), /* 10 */
60 N_("Continue"), /* 13 */
61 N_("Clone duplicate/bad blocks"), /* 14 */
62 N_("Delete file"), /* 15 */
63 N_("Suppress messages"),/* 16 */
64 N_("Unlink"), /* 17 */
68 * These messages are printed when we are preen mode and we will be
69 * automatically fixing the problem.
71 static const char *preen_msg[] = {
74 N_("CLEARED"), /* 2 */
75 N_("RELOCATED"), /* 3 */
76 N_("ALLOCATED"), /* 4 */
77 N_("EXPANDED"), /* 5 */
78 N_("RECONNECTED"), /* 6 */
79 N_("CREATED"), /* 7 */
80 N_("SALVAGED"), /* 8 */
81 N_("TRUNCATED"), /* 9 */
82 N_("INODE CLEARED"), /* 10 */
83 N_("ABORTED"), /* 11 */
85 N_("CONTINUING"), /* 13 */
86 N_("DUPLICATE/BAD BLOCKS CLONED"), /* 14 */
87 N_("FILE DELETED"), /* 15 */
88 N_("SUPPRESSED"), /* 16 */
89 N_("UNLINKED"), /* 17 */
92 static const struct e2fsck_problem problem_table[] = {
94 /* Pre-Pass 1 errors */
96 /* Block bitmap not in group */
97 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
98 PROMPT_RELOCATE, PR_LATCH_RELOC },
100 /* Inode bitmap not in group */
101 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
102 PROMPT_RELOCATE, PR_LATCH_RELOC },
104 /* Inode table not in group */
105 { PR_0_ITABLE_NOT_GROUP,
106 N_("@i table for @g %g is not in @g. (@b %b)\n"
107 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
108 PROMPT_RELOCATE, PR_LATCH_RELOC },
110 /* Superblock corrupt */
112 N_("\nThe @S could not be read or does not describe a correct ext2\n"
113 "@f. If the @v is valid and it really contains an ext2\n"
114 "@f (and not swap or ufs or something else), then the @S\n"
115 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
116 " e2fsck -b %S <@v>\n\n"),
117 PROMPT_NONE, PR_FATAL },
119 /* Filesystem size is wrong */
120 { PR_0_FS_SIZE_WRONG,
121 N_("The @f size (according to the @S) is %b @bs\n"
122 "The physical size of the @v is %c @bs\n"
123 "Either the @S or the partition table is likely to be corrupt!\n"),
126 /* Fragments not supported */
128 N_("@S @b_size = %b, fragsize = %c.\n"
129 "This version of e2fsck does not support fragment sizes different\n"
130 "from the @b size.\n"),
131 PROMPT_NONE, PR_FATAL },
133 /* Bad blocks_per_group */
134 { PR_0_BLOCKS_PER_GROUP,
135 N_("@S @bs_per_group = %b, should have been %c\n"),
136 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
138 /* Bad first_data_block */
139 { PR_0_FIRST_DATA_BLOCK,
140 N_("@S first_data_@b = %b, should have been %c\n"),
141 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
143 /* Adding UUID to filesystem */
145 N_("@f did not have a UUID; generating one.\n\n"),
149 { PR_0_RELOCATE_HINT,
150 N_("Note: if there is several inode or block bitmap blocks\n"
151 "which require relocation, or one part of the inode table\n"
152 "which must be moved, you may wish to try running e2fsck\n"
153 "with the '-b %S' option first. The problem may lie only\n"
154 "with the primary block group descriptor, and the backup\n"
155 "block group descriptor may be OK.\n\n"),
156 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
158 /* Miscellaneous superblock corruption */
159 { PR_0_MISC_CORRUPT_SUPER,
160 N_("Corruption found in @S. (%s = %N).\n"),
161 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
163 /* Error determing physical device size of filesystem */
164 { PR_0_GETSIZE_ERROR,
165 N_("Error determining size of the physical @v: %m\n"),
166 PROMPT_NONE, PR_FATAL },
168 /* Inode count in superblock is incorrect */
169 { PR_0_INODE_COUNT_WRONG,
170 N_("@i count in @S is %i, should be %j.\n"),
173 { PR_0_HURD_CLEAR_FILETYPE,
174 N_("The Hurd does not support the filetype feature.\n"),
177 /* Journal inode is invalid */
178 { PR_0_JOURNAL_BAD_INODE,
179 N_("@S has a bad ext3 @j (@i %i).\n"),
180 PROMPT_CLEAR, PR_PREEN_OK },
182 /* Superblock has a journal device (which we can't handle yet) */
183 { PR_0_JOURNAL_UNSUPP_DEV,
184 N_("@S has external ext3 @j @v (unsupported).\n"),
185 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_DEV },
187 /* Superblock has a bad journal device */
188 { PR_0_JOURNAL_BAD_DEV,
189 N_("@S has a bad ext3 @j (@v %X).\n"),
190 PROMPT_CLEAR, PR_PREEN_OK },
192 /* Superblock has a journal UUID (which we can't handle yet) */
193 { PR_0_JOURNAL_UNSUPP_UUID,
194 N_("@S has an ext3 @j UUID (unsupported).\n"),
195 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_UUID },
197 /* Superblock has a bad journal UUID */
198 { PR_0_JOURNAL_BAD_UUID,
199 N_("@S has a bad ext3 @j (UUID %s).\n"),
200 PROMPT_CLEAR, PR_PREEN_OK },
202 /* Journal has an unknown superblock type */
203 { PR_0_JOURNAL_UNSUPP_SUPER,
204 N_("Ext3 @j @S is unknown type %N (unsupported).\n"),
205 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
207 /* Journal superblock is corrupt */
208 { PR_0_JOURNAL_BAD_SUPER,
209 N_("Ext3 @j @S is corrupt.\n"),
210 PROMPT_FIX, PR_PREEN_OK },
212 /* Superblock flag should be cleared */
213 { PR_0_JOURNAL_HAS_JOURNAL,
214 N_("@S doesn't have has_journal flag, but has ext3 @j %s.\n"),
215 PROMPT_CLEAR, PR_PREEN_OK },
217 /* Superblock flag is incorrect */
218 { PR_0_JOURNAL_RECOVER_SET,
219 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
220 PROMPT_CLEAR, PR_PREEN_OK },
222 /* Journal should be reset */
223 { PR_0_JOURNAL_RESET_JOURNAL,
224 N_("*** WARNING *** leaving data in the @j may be DANGEROUS.\n"),
225 PROMPT_NONE, PR_PREEN_NOMSG|PR_AFTER_CODE, PR_0_JOURNAL_RESET_PROMPT},
227 /* Journal should be reset */
228 { PR_0_JOURNAL_RESET_PROMPT,
229 N_("ext3 recovery flag clear, but journal has data.\n"),
230 PROMPT_CLEAR, PR_PREEN_OK|PR_PREEN_NOMSG },
232 /* Clearing orphan inode */
233 { PR_0_ORPHAN_CLEAR_INODE,
234 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
237 /* Illegal block found in orphaned inode */
238 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
239 N_("@I @b #%B (%b) found in @o @i %i.\n"),
242 /* Already cleared block found in orphaned inode */
243 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
244 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
247 /* Illegal orphan inode in superblock */
248 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
249 N_("@I @o @i %i in @S.\n"),
252 /* Illegal inode in orphaned inode list */
253 { PR_0_ORPHAN_ILLEGAL_INODE,
254 N_("@I @i %i in @o @i list.\n"),
257 /* Filesystem revision is 0, but feature flags are set */
259 "@f has feature flag(s) set, but is a revision 0 @f. ",
260 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
264 /* Pass 1: Checking inodes, blocks, and sizes */
266 N_("Pass 1: Checking @is, @bs, and sizes\n"),
269 /* Root directory is not an inode */
270 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
273 /* Root directory has dtime set */
275 N_("@r has dtime set (probably due to old mke2fs). "),
276 PROMPT_FIX, PR_PREEN_OK },
278 /* Reserved inode has bad mode */
279 { PR_1_RESERVED_BAD_MODE,
280 N_("Reserved @i %i %Q has bad mode. "),
281 PROMPT_CLEAR, PR_PREEN_OK },
283 /* Deleted inode has zero dtime */
285 N_("@D @i %i has zero dtime. "),
286 PROMPT_FIX, PR_PREEN_OK },
288 /* Inode in use, but dtime set */
290 N_("@i %i is in use, but has dtime set. "),
291 PROMPT_FIX, PR_PREEN_OK },
293 /* Zero-length directory */
294 { PR_1_ZERO_LENGTH_DIR,
295 N_("@i %i is a @z @d. "),
296 PROMPT_CLEAR, PR_PREEN_OK },
298 /* Block bitmap conflicts with some other fs block */
300 N_("@g %g's @b @B at %b @C.\n"),
301 PROMPT_RELOCATE, 0 },
303 /* Inode bitmap conflicts with some other fs block */
305 N_("@g %g's @i @B at %b @C.\n"),
306 PROMPT_RELOCATE, 0 },
308 /* Inode table conflicts with some other fs block */
309 { PR_1_ITABLE_CONFLICT,
310 N_("@g %g's @i table at %b @C.\n"),
311 PROMPT_RELOCATE, 0 },
313 /* Block bitmap is on a bad block */
315 N_("@g %g's @b @B (%b) is bad. "),
316 PROMPT_RELOCATE, 0 },
318 /* Inode bitmap is on a bad block */
320 N_("@g %g's @i @B (%b) is bad. "),
321 PROMPT_RELOCATE, 0 },
323 /* Inode has incorrect i_size */
325 N_("@i %i, i_size is %Is, @s %N. "),
326 PROMPT_FIX, PR_PREEN_OK },
328 /* Inode has incorrect i_blocks */
330 N_("@i %i, i_@bs is %Ib, @s %N. "),
331 PROMPT_FIX, PR_PREEN_OK },
333 /* Illegal blocknumber in inode */
334 { PR_1_ILLEGAL_BLOCK_NUM,
335 N_("@I @b #%B (%b) in @i %i. "),
336 PROMPT_CLEAR, PR_LATCH_BLOCK },
338 /* Block number overlaps fs metadata */
339 { PR_1_BLOCK_OVERLAPS_METADATA,
340 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
341 PROMPT_CLEAR, PR_LATCH_BLOCK },
343 /* Inode has illegal blocks (latch question) */
344 { PR_1_INODE_BLOCK_LATCH,
345 N_("@i %i has illegal @b(s). "),
348 /* Too many bad blocks in inode */
349 { PR_1_TOO_MANY_BAD_BLOCKS,
350 N_("Too many illegal @bs in @i %i.\n"),
351 PROMPT_CLEAR_INODE, PR_NO_OK },
353 /* Illegal block number in bad block inode */
354 { PR_1_BB_ILLEGAL_BLOCK_NUM,
355 N_("@I @b #%B (%b) in bad @b @i. "),
356 PROMPT_CLEAR, PR_LATCH_BBLOCK },
358 /* Bad block inode has illegal blocks (latch question) */
359 { PR_1_INODE_BBLOCK_LATCH,
360 N_("Bad @b @i has illegal @b(s). "),
363 /* Duplicate or bad blocks in use! */
364 { PR_1_DUP_BLOCKS_PREENSTOP,
365 N_("Duplicate or bad @b in use!\n"),
368 /* Bad block used as bad block indirect block */
369 { PR_1_BBINODE_BAD_METABLOCK,
370 N_("Bad @b %b used as bad @b indirect @b?!?\n"),
371 PROMPT_NONE, PR_AFTER_CODE, PR_1_BBINODE_BAD_METABLOCK_PROMPT },
373 /* Inconsistency can't be fixed prompt */
374 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
375 N_("\nThis inconsistency can not be fixed with e2fsck; to fix it, use\n"
376 """dumpe2fs -b"" to dump out the bad @b "
377 "list and ""e2fsck -L filename""\n"
378 "to read it back in again.\n"),
379 PROMPT_CONTINUE, PR_PREEN_NOMSG },
381 /* Bad primary block */
382 { PR_1_BAD_PRIMARY_BLOCK,
383 N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
384 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
386 /* Bad primary block prompt */
387 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
388 N_("You can clear the this @b (and hope for the best) from the\n"
389 "bad @b list and hope that @b is really OK, but there are no\n"
391 PROMPT_CLEAR, PR_PREEN_NOMSG },
393 /* Bad primary superblock */
394 { PR_1_BAD_PRIMARY_SUPERBLOCK,
395 N_("The primary @S (%b) is on the bad @b list.\n"),
396 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
398 /* Bad primary block group descriptors */
399 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
400 N_("Block %b in the primary @g descriptors "
401 "is on the bad @b list\n"),
402 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
404 /* Bad superblock in group */
405 { PR_1_BAD_SUPERBLOCK,
406 N_("Warning: Group %g's @S (%b) is bad.\n"),
407 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
409 /* Bad block group descriptors in group */
410 { PR_1_BAD_GROUP_DESCRIPTORS,
411 N_("Warning: Group %g's copy of the @g descriptors has a bad "
413 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
415 /* Block claimed for no reason */
416 { PR_1_PROGERR_CLAIMED_BLOCK,
417 N_("Programming error? @b #%b claimed for no reason in "
418 "process_bad_@b.\n"),
419 PROMPT_NONE, PR_PREEN_OK },
421 /* Error allocating blocks for relocating metadata */
422 { PR_1_RELOC_BLOCK_ALLOCATE,
423 N_("@A %N @b(s) for %s: %m\n"),
424 PROMPT_NONE, PR_PREEN_OK },
426 /* Error allocating block buffer during relocation process */
427 { PR_1_RELOC_MEMORY_ALLOCATE,
428 N_("@A @b buffer for relocating %s\n"),
429 PROMPT_NONE, PR_PREEN_OK },
431 /* Relocating metadata group information from X to Y */
432 { PR_1_RELOC_FROM_TO,
433 N_("Relocating @g %g's %s from %b to %c...\n"),
434 PROMPT_NONE, PR_PREEN_OK },
436 /* Relocating metatdata group information to X */
438 N_("Relocating @g %g's %s to %c...\n"),
439 PROMPT_NONE, PR_PREEN_OK },
441 /* Block read error during relocation process */
442 { PR_1_RELOC_READ_ERR,
443 N_("Warning: could not read @b %b of %s: %m\n"),
444 PROMPT_NONE, PR_PREEN_OK },
446 /* Block write error during relocation process */
447 { PR_1_RELOC_WRITE_ERR,
448 N_("Warning: could not write @b %b for %s: %m\n"),
449 PROMPT_NONE, PR_PREEN_OK },
451 /* Error allocating inode bitmap */
452 { PR_1_ALLOCATE_IBITMAP_ERROR,
453 "@A @i @B (%N): %m\n",
454 PROMPT_NONE, PR_FATAL },
456 /* Error allocating block bitmap */
457 { PR_1_ALLOCATE_BBITMAP_ERROR,
458 "@A @b @B (%N): %m\n",
459 PROMPT_NONE, PR_FATAL },
461 /* Error allocating icount structure */
462 { PR_1_ALLOCATE_ICOUNT,
463 N_("@A icount link information: %m\n"),
464 PROMPT_NONE, PR_FATAL },
466 /* Error allocating dbcount */
467 { PR_1_ALLOCATE_DBCOUNT,
468 N_("@A @d @b array: %m\n"),
469 PROMPT_NONE, PR_FATAL },
471 /* Error while scanning inodes */
473 N_("Error while scanning @is (%i): %m\n"),
474 PROMPT_NONE, PR_FATAL },
476 /* Error while iterating over blocks */
477 { PR_1_BLOCK_ITERATE,
478 N_("Error while iterating over @bs in @i %i: %m\n"),
479 PROMPT_NONE, PR_FATAL },
481 /* Error while storing inode count information */
483 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
484 PROMPT_NONE, PR_FATAL },
486 /* Error while storing directory block information */
488 N_("Error storing @d @b information "
489 "(@i=%i, @b=%b, num=%N): %m\n"),
490 PROMPT_NONE, PR_FATAL },
492 /* Error while reading inode (for clearing) */
494 N_("Error reading @i %i: %m\n"),
495 PROMPT_NONE, PR_FATAL },
497 /* Suppress messages prompt */
498 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
500 /* Filesystem contains large files, but has no such flag in sb */
501 { PR_1_FEATURE_LARGE_FILES,
502 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
505 /* Imagic flag set on an inode when filesystem doesn't support it */
507 N_("@i %i has imagic flag set. "),
510 /* Immutable flag set on a device or socket inode */
511 { PR_1_SET_IMMUTABLE,
512 N_("Special (@v/socket/fifo) @i %i has immutable or "
513 "append-only flag set.\n"),
514 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
516 /* Compression flag set on an inode when filesystem doesn't support it */
518 N_("@i %i has @cion flag set on @f without @cion support. "),
521 /* Non-zero size for device, fifo or socket inode */
523 "Special (@v/socket/fifo) @i %i has non-zero size. ",
524 PROMPT_FIX, PR_PREEN_OK },
526 /* Filesystem revision is 0, but feature flags are set */
528 "@f has feature flag(s) set, but is a revision 0 @f. ",
529 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
531 /* Journal inode is not in use, but contains data */
532 { PR_1_JOURNAL_INODE_NOT_CLEAR,
533 "@j @i is not in use, but contains data. ",
534 PROMPT_CLEAR, PR_PREEN_OK },
536 /* Journal has bad mode */
537 { PR_1_JOURNAL_BAD_MODE,
538 N_("Journal is not regular file. "),
539 PROMPT_FIX, PR_PREEN_OK },
543 /* Pass 1B: Rescan for duplicate/bad blocks */
545 N_("Duplicate @bs found... invoking duplicate @b passes.\n"
546 "Pass 1B: Rescan for duplicate/bad @bs\n"),
549 /* Duplicate/bad block(s) header */
550 { PR_1B_DUP_BLOCK_HEADER,
551 N_("Duplicate/bad @b(s) in @i %i:"),
554 /* Duplicate/bad block(s) in inode */
557 PROMPT_NONE, PR_LATCH_DBLOCK },
559 /* Duplicate/bad block(s) end */
560 { PR_1B_DUP_BLOCK_END,
564 /* Error while scanning inodes */
566 N_("Error while scanning inodes (%i): %m\n"),
567 PROMPT_NONE, PR_FATAL },
569 /* Error allocating inode bitmap */
570 { PR_1B_ALLOCATE_IBITMAP_ERROR,
571 N_("@A @i @B (inode_dup_map): %m\n"),
572 PROMPT_NONE, PR_FATAL },
574 /* Error while iterating over blocks */
575 { PR_1B_BLOCK_ITERATE,
576 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
579 /* Pass 1C: Scan directories for inodes with dup blocks. */
581 N_("Pass 1C: Scan directories for @is with dup @bs.\n"),
585 /* Pass 1D: Reconciling duplicate blocks */
587 N_("Pass 1D: Reconciling duplicate @bs\n"),
590 /* File has duplicate blocks */
592 N_("File %Q (@i #%i, mod time %IM) \n"
593 " has %B duplicate @b(s), shared with %N file(s):\n"),
596 /* List of files sharing duplicate blocks */
597 { PR_1D_DUP_FILE_LIST,
598 N_("\t%Q (@i #%i, mod time %IM)\n"),
601 /* File sharing blocks with filesystem metadata */
602 { PR_1D_SHARE_METADATA,
603 N_("\t<@f metadata>\n"),
606 /* Report of how many duplicate/bad inodes */
607 { PR_1D_NUM_DUP_INODES,
608 N_("(There are %N @is containing duplicate/bad @bs.)\n\n"),
611 /* Duplicated blocks already reassigned or cloned. */
612 { PR_1D_DUP_BLOCKS_DEALT,
613 N_("Duplicated @bs already reassigned or cloned.\n\n"),
616 /* Clone duplicate/bad blocks? */
617 { PR_1D_CLONE_QUESTION,
618 "", PROMPT_CLONE, PR_NO_OK },
621 { PR_1D_DELETE_QUESTION,
622 "", PROMPT_DELETE, 0 },
624 /* Couldn't clone file (error) */
626 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
630 /* Pass 2: Checking directory structure */
632 N_("Pass 2: Checking @d structure\n"),
635 /* Bad inode number for '.' */
636 { PR_2_BAD_INODE_DOT,
637 N_("Bad @i number for '.' in @d @i %i.\n"),
640 /* Directory entry has bad inode number */
642 N_("@E has bad @i #: %Di.\n"),
645 /* Directory entry has deleted or unused inode */
647 N_("@E has @D/unused @i %Di. "),
648 PROMPT_CLEAR, PR_PREEN_OK },
650 /* Directry entry is link to '.' */
655 /* Directory entry points to inode now located in a bad block */
657 N_("@E points to @i (%Di) located in a bad @b.\n"),
660 /* Directory entry contains a link to a directory */
662 N_("@E @L to @d %P (%Di).\n"),
665 /* Directory entry contains a link to the root directry */
667 N_("@E @L to the @r.\n"),
670 /* Directory entry has illegal characters in its name */
672 N_("@E has illegal characters in its name.\n"),
675 /* Missing '.' in directory inode */
677 N_("Missing '.' in @d @i %i.\n"),
680 /* Missing '..' in directory inode */
681 { PR_2_MISSING_DOT_DOT,
682 N_("Missing '..' in @d @i %i.\n"),
685 /* First entry in directory inode doesn't contain '.' */
687 N_("First @e '%Dn' (inode=%Di) in @d @i %i (%p) @s '.'\n"),
690 /* Second entry in directory inode doesn't contain '..' */
691 { PR_2_2ND_NOT_DOT_DOT,
692 N_("Second @e '%Dn' (inode=%Di) in @d @i %i @s '..'\n"),
695 /* i_faddr should be zero */
697 N_("i_faddr @F %IF, @s zero.\n"),
700 /* i_file_acl should be zero */
701 { PR_2_FILE_ACL_ZERO,
702 N_("i_file_acl @F %If, @s zero.\n"),
705 /* i_dir_acl should be zero */
707 N_("i_dir_acl @F %Id, @s zero.\n"),
710 /* i_frag should be zero */
712 N_("i_frag @F %N, @s zero.\n"),
715 /* i_fsize should be zero */
717 N_("i_fsize @F %N, @s zero.\n"),
720 /* inode has bad mode */
722 N_("@i %i (%Q) has a bad mode (%Im).\n"),
725 /* directory corrupted */
726 { PR_2_DIR_CORRUPTED,
727 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
730 /* filename too long */
731 { PR_2_FILENAME_LONG,
732 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
733 PROMPT_TRUNCATE, 0 },
735 /* Directory inode has a missing block (hole) */
736 { PR_2_DIRECTORY_HOLE,
737 N_("@d @i %i has an unallocated @b #%B. "),
738 PROMPT_ALLOCATE, 0 },
740 /* '.' is not NULL terminated */
741 { PR_2_DOT_NULL_TERM,
742 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
745 /* '..' is not NULL terminated */
746 { PR_2_DOT_DOT_NULL_TERM,
747 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
750 /* Illegal character device inode */
752 N_("@i %i (%Q) is an @I character @v.\n"),
755 /* Illegal block device inode */
756 { PR_2_BAD_BLOCK_DEV,
757 N_("@i %i (%Q) is an @I @b @v.\n"),
760 /* Duplicate '.' entry */
762 N_("@E is duplicate '.' @e.\n"),
765 /* Duplicate '..' entry */
767 N_("@E is duplicate '..' @e.\n"),
770 /* Internal error: couldn't find dir_info */
772 N_("Internal error: couldn't find dir_info for %i.\n"),
773 PROMPT_NONE, PR_FATAL },
775 /* Final rec_len is wrong */
777 N_("@E has rec_len of %dr, should be %N.\n"),
780 /* Error allocating icount structure */
781 { PR_2_ALLOCATE_ICOUNT,
782 N_("@A icount structure: %m\n"),
783 PROMPT_NONE, PR_FATAL },
785 /* Error iterating over directory blocks */
786 { PR_2_DBLIST_ITERATE,
787 N_("Error interating over @d @bs: %m\n"),
788 PROMPT_NONE, PR_FATAL },
790 /* Error reading directory block */
791 { PR_2_READ_DIRBLOCK,
792 N_("Error reading @d @b %b (@i %i): %m\n"),
793 PROMPT_CONTINUE, 0 },
795 /* Error writing directory block */
796 { PR_2_WRITE_DIRBLOCK,
797 N_("Error writing @d @b %b (@i %i): %m\n"),
798 PROMPT_CONTINUE, 0 },
800 /* Error allocating new directory block */
801 { PR_2_ALLOC_DIRBOCK,
802 N_("@A new @d @b for @i %i (%s): %m\n"),
805 /* Error deallocating inode */
806 { PR_2_DEALLOC_INODE,
807 N_("Error deallocating @i %i: %m\n"),
808 PROMPT_NONE, PR_FATAL },
810 /* Directory entry for '.' is big. Split? */
812 N_("@d @e for '.' is big. "),
813 PROMPT_SPLIT, PR_NO_OK },
815 /* Illegal FIFO inode */
817 N_("@i %i (%Q) is an @I FIFO.\n"),
820 /* Illegal socket inode */
822 N_("@i %i (%Q) is an @I socket.\n"),
825 /* Directory filetype not set */
827 N_("Setting filetype for @E to %N.\n"),
828 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
830 /* Directory filetype incorrect */
832 N_("@E has an incorrect filetype (was %dt, should be %N)\n"),
835 /* Directory filetype set on filesystem */
836 { PR_2_CLEAR_FILETYPE,
837 N_("@E has filetype set\n"),
838 PROMPT_CLEAR, PR_PREEN_OK },
840 /* Directory filename is null */
842 N_("@E has a zero-length name\n"),
847 /* Pass 3: Checking directory connectivity */
849 N_("Pass 3: Checking @d connectivity\n"),
852 /* Root inode not allocated */
853 { PR_3_NO_ROOT_INODE,
854 N_("@r not allocated. "),
855 PROMPT_ALLOCATE, 0 },
857 /* No room in lost+found */
858 { PR_3_EXPAND_LF_DIR,
859 N_("No room in @l @d. "),
862 /* Unconnected directory inode */
863 { PR_3_UNCONNECTED_DIR,
864 N_("Unconnected @d @i %i (%p)\n"),
867 /* /lost+found not found */
869 N_("/@l not found. "),
870 PROMPT_CREATE, PR_PREEN_OK },
872 /* .. entry is incorrect */
874 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
877 /* Bad or non-existent /lost+found. Cannot reconnect */
879 N_("Bad or non-existent /@l. Cannot reconnect\n"),
882 /* Could not expand /lost+found */
883 { PR_3_CANT_EXPAND_LPF,
884 N_("Could not expand /@l: %m\n"),
887 /* Could not reconnect inode */
888 { PR_3_CANT_RECONNECT,
889 N_("Could not reconnect %i: %m\n"),
892 /* Error while trying to find /lost+found */
894 N_("Error while trying to find /@l: %m\n"),
897 /* Error in ext2fs_new_block while creating /lost+found */
898 { PR_3_ERR_LPF_NEW_BLOCK,
899 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
902 /* Error in ext2fs_new_inode while creating /lost+found */
903 { PR_3_ERR_LPF_NEW_INODE,
904 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
907 /* Error in ext2fs_new_dir_block while creating /lost+found */
908 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
909 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
912 /* Error while writing directory block for /lost+found */
913 { PR_3_ERR_LPF_WRITE_BLOCK,
914 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
917 /* Error while adjusting inode count */
919 N_("Error while adjusting @i count on @i %i\n"),
922 /* Couldn't fix parent directory -- error */
923 { PR_3_FIX_PARENT_ERR,
924 N_("Couldn't fix parent of @i %i: %m\n\n"),
927 /* Couldn't fix parent directory -- couldn't find it */
928 { PR_3_FIX_PARENT_NOFIND,
929 N_("Couldn't fix parent of @i %i: Couldn't find parent @d entry\n\n"),
932 /* Error allocating inode bitmap */
933 { PR_3_ALLOCATE_IBITMAP_ERROR,
934 N_("@A @i @B (%N): %m\n"),
935 PROMPT_NONE, PR_FATAL },
937 /* Error creating root directory */
938 { PR_3_CREATE_ROOT_ERROR,
939 N_("Error creating root @d (%s): %m\n"),
940 PROMPT_NONE, PR_FATAL },
942 /* Error creating lost and found directory */
943 { PR_3_CREATE_LPF_ERROR,
944 N_("Error creating /@l @d (%s): %m\n"),
945 PROMPT_NONE, PR_FATAL },
947 /* Root inode is not directory; aborting */
948 { PR_3_ROOT_NOT_DIR_ABORT,
949 N_("@r is not a @d; aborting.\n"),
950 PROMPT_NONE, PR_FATAL },
952 /* Cannot proceed without a root inode. */
953 { PR_3_NO_ROOT_INODE_ABORT,
954 N_("Cannot proceed without a @r.\n"),
955 PROMPT_NONE, PR_FATAL },
957 /* Internal error: couldn't find dir_info */
959 N_("Internal error: couldn't find dir_info for %i.\n"),
960 PROMPT_NONE, PR_FATAL },
962 /* Lost+found not a directory */
964 N_("/@l is not a @d (ino=%i)\n"),
969 /* Pass 4: Checking reference counts */
971 N_("Pass 4: Checking reference counts\n"),
974 /* Unattached zero-length inode */
975 { PR_4_ZERO_LEN_INODE,
977 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
979 /* Unattached inode */
980 { PR_4_UNATTACHED_INODE,
984 /* Inode ref count wrong */
985 { PR_4_BAD_REF_COUNT,
986 N_("@i %i ref count is %Il, @s %N. "),
987 PROMPT_FIX, PR_PREEN_OK },
989 { PR_4_INCONSISTENT_COUNT,
990 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
991 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
992 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
993 "They should be the same!\n"),
998 /* Pass 5: Checking group summary information */
1000 N_("Pass 5: Checking @g summary information\n"),
1003 /* Padding at end of inode bitmap is not set. */
1004 { PR_5_INODE_BMAP_PADDING,
1005 N_("Padding at end of @i @B is not set. "),
1006 PROMPT_FIX, PR_PREEN_OK },
1008 /* Padding at end of block bitmap is not set. */
1009 { PR_5_BLOCK_BMAP_PADDING,
1010 N_("Padding at end of @b @B is not set. "),
1011 PROMPT_FIX, PR_PREEN_OK },
1013 /* Block bitmap differences header */
1014 { PR_5_BLOCK_BITMAP_HEADER,
1015 N_("@b @B differences: "),
1016 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
1018 /* Block not used, but marked in bitmap */
1019 { PR_5_UNUSED_BLOCK,
1021 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
1023 /* Block used, but not marked used in bitmap */
1026 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
1028 /* Block bitmap differences end */
1029 { PR_5_BLOCK_BITMAP_END,
1031 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
1033 /* Inode bitmap differences header */
1034 { PR_5_INODE_BITMAP_HEADER,
1035 N_("@i @B differences: "),
1036 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
1038 /* Inode not used, but marked in bitmap */
1039 { PR_5_UNUSED_INODE,
1041 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
1043 /* Inode used, but not marked used in bitmap */
1046 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
1048 /* Inode bitmap differences end */
1049 { PR_5_INODE_BITMAP_END,
1051 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
1053 /* Free inodes count for group wrong */
1054 { PR_5_FREE_INODE_COUNT_GROUP,
1055 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
1056 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
1058 /* Directories count for group wrong */
1059 { PR_5_FREE_DIR_COUNT_GROUP,
1060 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
1061 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
1063 /* Free inodes count wrong */
1064 { PR_5_FREE_INODE_COUNT,
1065 N_("Free @is count wrong (%i, counted=%j).\n"),
1066 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
1068 /* Free blocks count for group wrong */
1069 { PR_5_FREE_BLOCK_COUNT_GROUP,
1070 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
1071 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
1073 /* Free blocks count wrong */
1074 { PR_5_FREE_BLOCK_COUNT,
1075 N_("Free @bs count wrong (%b, counted=%c).\n"),
1076 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
1078 /* Programming error: bitmap endpoints don't match */
1079 { PR_5_BMAP_ENDPOINTS,
1080 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
1081 "match calculated @B endpoints (%i, %j)\n"),
1082 PROMPT_NONE, PR_FATAL },
1084 /* Internal error: fudging end of bitmap */
1085 { PR_5_FUDGE_BITMAP_ERROR,
1086 N_("Internal error: fudging end of bitmap (%N)\n"),
1087 PROMPT_NONE, PR_FATAL },
1089 /* Error copying in replacement inode bitmap */
1090 { PR_5_COPY_IBITMAP_ERROR,
1091 "Error copying in replacement @i @B: %m\n",
1092 PROMPT_NONE, PR_FATAL },
1094 /* Error copying in replacement block bitmap */
1095 { PR_5_COPY_BBITMAP_ERROR,
1096 "Error copying in replacement @b @B: %m\n",
1097 PROMPT_NONE, PR_FATAL },
1103 * This is the latch flags register. It allows several problems to be
1104 * "latched" together. This means that the user has to answer but one
1105 * question for the set of problems, and all of the associated
1106 * problems will be either fixed or not fixed.
1108 static struct latch_descr pr_latch_info[] = {
1109 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
1110 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
1111 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
1112 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
1113 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
1114 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
1118 static const struct e2fsck_problem *find_problem(int code)
1122 for (i=0; problem_table[i].e2p_code; i++) {
1123 if (problem_table[i].e2p_code == code)
1124 return &problem_table[i];
1129 static struct latch_descr *find_latch(int code)
1133 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
1134 if (pr_latch_info[i].latch_code == code)
1135 return &pr_latch_info[i];
1140 int end_problem_latch(e2fsck_t ctx, int mask)
1142 struct latch_descr *ldesc;
1143 struct problem_context pctx;
1146 ldesc = find_latch(mask);
1147 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
1148 clear_problem_context(&pctx);
1149 answer = fix_problem(ctx, ldesc->end_message, &pctx);
1151 ldesc->flags &= ~(PRL_VARIABLE);
1155 int set_latch_flags(int mask, int setflags, int clearflags)
1157 struct latch_descr *ldesc;
1159 ldesc = find_latch(mask);
1162 ldesc->flags |= setflags;
1163 ldesc->flags &= ~clearflags;
1167 int get_latch_flags(int mask, int *value)
1169 struct latch_descr *ldesc;
1171 ldesc = find_latch(mask);
1174 *value = ldesc->flags;
1178 void clear_problem_context(struct problem_context *ctx)
1180 memset(ctx, 0, sizeof(struct problem_context));
1185 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
1187 ext2_filsys fs = ctx->fs;
1188 const struct e2fsck_problem *ptr;
1189 struct latch_descr *ldesc = 0;
1190 const char *message;
1191 int def_yn, answer, ans;
1192 int print_answer = 0;
1195 ptr = find_problem(code);
1197 printf(_("Unhandled error code (%d)!\n"), code);
1201 if ((ptr->flags & PR_NO_DEFAULT) ||
1202 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
1203 (ctx->options & E2F_OPT_NO))
1207 * Do special latch processing. This is where we ask the
1208 * latch question, if it exists
1210 if (ptr->flags & PR_LATCH_MASK) {
1211 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
1212 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
1213 ans = fix_problem(ctx, ldesc->question, pctx);
1215 ldesc->flags |= PRL_YES;
1217 ldesc->flags |= PRL_NO;
1218 ldesc->flags |= PRL_LATCHED;
1220 if (ldesc->flags & PRL_SUPPRESS)
1223 if ((ptr->flags & PR_PREEN_NOMSG) &&
1224 (ctx->options & E2F_OPT_PREEN))
1226 if ((ptr->flags & PR_NO_NOMSG) &&
1227 (ctx->options & E2F_OPT_NO))
1230 message = ptr->e2p_description;
1231 if (ctx->options & E2F_OPT_PREEN) {
1232 printf("%s: ", ctx->device_name);
1234 if (ptr->e2p_preen_msg)
1235 message = ptr->e2p_preen_msg;
1238 print_e2fsck_message(ctx, _(message), pctx, 1);
1240 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
1243 if (ptr->flags & PR_FATAL)
1244 fatal_error(ctx, 0);
1246 if (ptr->prompt == PROMPT_NONE) {
1247 if (ptr->flags & PR_NOCOLLATE)
1252 if (ctx->options & E2F_OPT_PREEN) {
1254 if (!(ptr->flags & PR_PREEN_NOMSG))
1256 } else if ((ptr->flags & PR_LATCH_MASK) &&
1257 (ldesc->flags & (PRL_YES | PRL_NO))) {
1260 if (ldesc->flags & PRL_YES)
1265 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
1266 if (!answer && !(ptr->flags & PR_NO_OK))
1267 ext2fs_unmark_valid(fs);
1270 printf("%s.\n", answer ?
1271 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
1275 if ((ptr->prompt == PROMPT_ABORT) && answer)
1276 fatal_error(ctx, 0);
1278 if (ptr->flags & PR_AFTER_CODE)
1279 answer = fix_problem(ctx, ptr->second_code, pctx);