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 device 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 <device>\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 device 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 device: %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 journal (@i %N).\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 journal device (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 journal (device %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 journal 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 journal (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 journal @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 journal @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 journal %s.\n"),
215 PROMPT_DELETE, 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 journal.\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 journal 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 },
234 /* Pass 1: Checking inodes, blocks, and sizes */
236 N_("Pass 1: Checking @is, @bs, and sizes\n"),
239 /* Root directory is not an inode */
240 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
243 /* Root directory has dtime set */
245 N_("@r has dtime set (probably due to old mke2fs). "),
246 PROMPT_FIX, PR_PREEN_OK },
248 /* Reserved inode has bad mode */
249 { PR_1_RESERVED_BAD_MODE,
250 N_("Reserved @i %i has bad mode. "),
251 PROMPT_CLEAR, PR_PREEN_OK },
253 /* Deleted inode has zero dtime */
255 N_("@D @i %i has zero dtime. "),
256 PROMPT_FIX, PR_PREEN_OK },
258 /* Inode in use, but dtime set */
260 N_("@i %i is in use, but has dtime set. "),
261 PROMPT_FIX, PR_PREEN_OK },
263 /* Zero-length directory */
264 { PR_1_ZERO_LENGTH_DIR,
265 N_("@i %i is a @z @d. "),
266 PROMPT_CLEAR, PR_PREEN_OK },
268 /* Block bitmap conflicts with some other fs block */
270 N_("@g %g's @b @B at %b @C.\n"),
271 PROMPT_RELOCATE, 0 },
273 /* Inode bitmap conflicts with some other fs block */
275 N_("@g %g's @i @B at %b @C.\n"),
276 PROMPT_RELOCATE, 0 },
278 /* Inode table conflicts with some other fs block */
279 { PR_1_ITABLE_CONFLICT,
280 N_("@g %g's @i table at %b @C.\n"),
281 PROMPT_RELOCATE, 0 },
283 /* Block bitmap is on a bad block */
285 N_("@g %g's @b @B (%b) is bad. "),
286 PROMPT_RELOCATE, 0 },
288 /* Inode bitmap is on a bad block */
290 N_("@g %g's @i @B (%b) is bad. "),
291 PROMPT_RELOCATE, 0 },
293 /* Inode has incorrect i_size */
295 N_("@i %i, i_size is %Is, @s %N. "),
296 PROMPT_FIX, PR_PREEN_OK },
298 /* Inode has incorrect i_blocks */
300 N_("@i %i, i_@bs is %Ib, @s %N. "),
301 PROMPT_FIX, PR_PREEN_OK },
303 /* Illegal block number in inode */
304 { PR_1_ILLEGAL_BLOCK_NUM,
305 N_("@I @b #%B (%b) in @i %i. "),
306 PROMPT_CLEAR, PR_LATCH_BLOCK },
308 /* Block number overlaps fs metadata */
309 { PR_1_BLOCK_OVERLAPS_METADATA,
310 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
311 PROMPT_CLEAR, PR_LATCH_BLOCK },
313 /* Inode has illegal blocks (latch question) */
314 { PR_1_INODE_BLOCK_LATCH,
315 N_("@i %i has illegal @b(s). "),
318 /* Too many bad blocks in inode */
319 { PR_1_TOO_MANY_BAD_BLOCKS,
320 N_("Too many illegal @bs in @i %i.\n"),
321 PROMPT_CLEAR_INODE, PR_NO_OK },
323 /* Illegal block number in bad block inode */
324 { PR_1_BB_ILLEGAL_BLOCK_NUM,
325 N_("@I @b #%B (%b) in bad @b @i. "),
326 PROMPT_CLEAR, PR_LATCH_BBLOCK },
328 /* Bad block inode has illegal blocks (latch question) */
329 { PR_1_INODE_BBLOCK_LATCH,
330 N_("Bad @b @i has illegal @b(s). "),
333 /* Duplicate or bad blocks in use! */
334 { PR_1_DUP_BLOCKS_PREENSTOP,
335 N_("Duplicate or bad @b in use!\n"),
338 /* Bad block used as bad block indirect block */
339 { PR_1_BBINODE_BAD_METABLOCK,
340 N_("Bad @b %b used as bad @b indirect @b?!?\n"),
341 PROMPT_NONE, PR_AFTER_CODE, PR_1_BBINODE_BAD_METABLOCK_PROMPT },
343 /* Inconsistency can't be fixed prompt */
344 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
345 N_("\nThis inconsistency can not be fixed with e2fsck; to fix it, use\n"
346 """dumpe2fs -b"" to dump out the bad @b "
347 "list and ""e2fsck -L filename""\n"
348 "to read it back in again.\n"),
349 PROMPT_CONTINUE, PR_PREEN_NOMSG },
351 /* Bad primary block */
352 { PR_1_BAD_PRIMARY_BLOCK,
353 N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
354 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
356 /* Bad primary block prompt */
357 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
358 N_("You can clear the this @b (and hope for the best) from the\n"
359 "bad @b list and hope that @b is really OK, but there are no\n"
361 PROMPT_CLEAR, PR_PREEN_NOMSG },
363 /* Bad primary superblock */
364 { PR_1_BAD_PRIMARY_SUPERBLOCK,
365 N_("The primary @S (%b) is on the bad @b list.\n"),
366 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
368 /* Bad primary block group descriptors */
369 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
370 N_("Block %b in the primary @g descriptors "
371 "is on the bad @b list\n"),
372 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
374 /* Bad superblock in group */
375 { PR_1_BAD_SUPERBLOCK,
376 N_("Warning: Group %g's @S (%b) is bad.\n"),
377 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
379 /* Bad block group descriptors in group */
380 { PR_1_BAD_GROUP_DESCRIPTORS,
381 N_("Warning: Group %g's copy of the @g descriptors has a bad "
383 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
385 /* Block claimed for no reason */
386 { PR_1_PROGERR_CLAIMED_BLOCK,
387 N_("Programming error? @b #%b claimed for no reason in "
388 "process_bad_@b.\n"),
389 PROMPT_NONE, PR_PREEN_OK },
391 /* Error allocating blocks for relocating metadata */
392 { PR_1_RELOC_BLOCK_ALLOCATE,
393 N_("@A %N @b(s) for %s: %m\n"),
394 PROMPT_NONE, PR_PREEN_OK },
396 /* Error allocating block buffer during relocation process */
397 { PR_1_RELOC_MEMORY_ALLOCATE,
398 N_("@A @b buffer for relocating %s\n"),
399 PROMPT_NONE, PR_PREEN_OK },
401 /* Relocating metadata group information from X to Y */
402 { PR_1_RELOC_FROM_TO,
403 N_("Relocating @g %g's %s from %b to %c...\n"),
404 PROMPT_NONE, PR_PREEN_OK },
406 /* Relocating metatdata group information to X */
408 N_("Relocating @g %g's %s to %c...\n"),
409 PROMPT_NONE, PR_PREEN_OK },
411 /* Block read error during relocation process */
412 { PR_1_RELOC_READ_ERR,
413 N_("Warning: could not read @b %b of %s: %m\n"),
414 PROMPT_NONE, PR_PREEN_OK },
416 /* Block write error during relocation process */
417 { PR_1_RELOC_WRITE_ERR,
418 N_("Warning: could not write @b %b for %s: %m\n"),
419 PROMPT_NONE, PR_PREEN_OK },
421 /* Error allocating inode bitmap */
422 { PR_1_ALLOCATE_IBITMAP_ERROR,
423 "@A @i @B (%N): %m\n",
424 PROMPT_NONE, PR_FATAL },
426 /* Error allocating block bitmap */
427 { PR_1_ALLOCATE_BBITMAP_ERROR,
428 "@A @b @B (%N): %m\n",
429 PROMPT_NONE, PR_FATAL },
431 /* Error allocating icount structure */
432 { PR_1_ALLOCATE_ICOUNT,
433 N_("@A icount link information: %m\n"),
434 PROMPT_NONE, PR_FATAL },
436 /* Error allocating dbcount */
437 { PR_1_ALLOCATE_DBCOUNT,
438 N_("@A @d @b array: %m\n"),
439 PROMPT_NONE, PR_FATAL },
441 /* Error while scanning inodes */
443 N_("Error while scanning @is (%i): %m\n"),
444 PROMPT_NONE, PR_FATAL },
446 /* Error while iterating over blocks */
447 { PR_1_BLOCK_ITERATE,
448 N_("Error while iterating over blocks in @i %i: %m\n"),
449 PROMPT_NONE, PR_FATAL },
451 /* Error while storing inode count information */
453 N_("Error storing @i count information (inode=%i, count=%N): %m\n"),
454 PROMPT_NONE, PR_FATAL },
456 /* Error while storing directory block information */
458 N_("Error storing @d @b information "
459 "(inode=%i, block=%b, num=%N): %m\n"),
460 PROMPT_NONE, PR_FATAL },
462 /* Error while reading inode (for clearing) */
464 N_("Error reading @i %i: %m\n"),
465 PROMPT_NONE, PR_FATAL },
467 /* Suppress messages prompt */
468 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
470 /* Filesystem contains large files, but has no such flag in sb */
471 { PR_1_FEATURE_LARGE_FILES,
472 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
475 /* Imagic flag set on an inode when filesystem doesn't support it */
477 N_("@i %i has imagic flag set. "),
480 /* Immutable flag set on a device or socket inode */
481 { PR_1_SET_IMMUTABLE,
482 N_("Special (device/socket/fifo) @i %i has immutable or "
483 "append-only flag set.\n"),
484 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
486 /* Compression flag set on an inode when filesystem doesn't support it */
488 N_("@i %i has @cion flag set on @f without @cion support. "),
491 /* Non-zero size for device, fifo or socket inode */
493 "Special (device/socket/fifo) @i %i has non-zero size. ",
494 PROMPT_FIX, PR_PREEN_OK },
498 /* Pass 1B: Rescan for duplicate/bad blocks */
500 N_("Duplicate @bs found... invoking duplicate @b passes.\n"
501 "Pass 1B: Rescan for duplicate/bad @bs\n"),
504 /* Duplicate/bad block(s) header */
505 { PR_1B_DUP_BLOCK_HEADER,
506 N_("Duplicate/bad @b(s) in @i %i:"),
509 /* Duplicate/bad block(s) in inode */
512 PROMPT_NONE, PR_LATCH_DBLOCK },
514 /* Duplicate/bad block(s) end */
515 { PR_1B_DUP_BLOCK_END,
519 /* Error while scanning inodes */
521 N_("Error while scanning inodes (%i): %m\n"),
522 PROMPT_NONE, PR_FATAL },
524 /* Error allocating inode bitmap */
525 { PR_1B_ALLOCATE_IBITMAP_ERROR,
526 N_("@A @i @B (inode_dup_map): %m\n"),
527 PROMPT_NONE, PR_FATAL },
530 /* Pass 1C: Scan directories for inodes with dup blocks. */
532 N_("Pass 1C: Scan directories for @is with dup @bs.\n"),
536 /* Pass 1D: Reconciling duplicate blocks */
538 N_("Pass 1D: Reconciling duplicate @bs\n"),
541 /* File has duplicate blocks */
543 N_("File %Q (@i #%i, mod time %IM) \n"
544 " has %B duplicate @b(s), shared with %N file(s):\n"),
547 /* List of files sharing duplicate blocks */
548 { PR_1D_DUP_FILE_LIST,
549 N_("\t%Q (@i #%i, mod time %IM)\n"),
552 /* File sharing blocks with filesystem metadata */
553 { PR_1D_SHARE_METADATA,
554 N_("\t<@f metadata>\n"),
557 /* Report of how many duplicate/bad inodes */
558 { PR_1D_NUM_DUP_INODES,
559 N_("(There are %N @is containing duplicate/bad @bs.)\n\n"),
562 /* Duplicated blocks already reassigned or cloned. */
563 { PR_1D_DUP_BLOCKS_DEALT,
564 N_("Duplicated @bs already reassigned or cloned.\n\n"),
567 /* Clone duplicate/bad blocks? */
568 { PR_1D_CLONE_QUESTION,
569 "", PROMPT_CLONE, PR_NO_OK },
572 { PR_1D_DELETE_QUESTION,
573 "", PROMPT_DELETE, 0 },
575 /* Couldn't clone file (error) */
577 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
581 /* Pass 2: Checking directory structure */
583 N_("Pass 2: Checking @d structure\n"),
586 /* Bad inode number for '.' */
587 { PR_2_BAD_INODE_DOT,
588 N_("Bad @i number for '.' in @d @i %i.\n"),
591 /* Directory entry has bad inode number */
593 N_("@E has bad @i #: %Di.\n"),
596 /* Directory entry has deleted or unused inode */
598 N_("@E has @D/unused @i %Di. "),
599 PROMPT_CLEAR, PR_PREEN_OK },
601 /* Directry entry is link to '.' */
606 /* Directory entry points to inode now located in a bad block */
608 N_("@E points to @i (%Di) located in a bad @b.\n"),
611 /* Directory entry contains a link to a directory */
613 N_("@E @L to @d %P (%Di).\n"),
616 /* Directory entry contains a link to the root directry */
618 N_("@E @L to the @r.\n"),
621 /* Directory entry has illegal characters in its name */
623 N_("@E has illegal characters in its name.\n"),
626 /* Missing '.' in directory inode */
628 N_("Missing '.' in @d @i %i.\n"),
631 /* Missing '..' in directory inode */
632 { PR_2_MISSING_DOT_DOT,
633 N_("Missing '..' in @d @i %i.\n"),
636 /* First entry in directory inode doesn't contain '.' */
638 N_("First @e '%Dn' (inode=%Di) in @d @i %i (%p) @s '.'\n"),
641 /* Second entry in directory inode doesn't contain '..' */
642 { PR_2_2ND_NOT_DOT_DOT,
643 N_("Second @e '%Dn' (inode=%Di) in @d @i %i @s '..'\n"),
646 /* i_faddr should be zero */
648 N_("i_faddr @F %IF, @s zero.\n"),
651 /* i_file_acl should be zero */
652 { PR_2_FILE_ACL_ZERO,
653 N_("i_file_acl @F %If, @s zero.\n"),
656 /* i_dir_acl should be zero */
658 N_("i_dir_acl @F %Id, @s zero.\n"),
661 /* i_frag should be zero */
663 N_("i_frag @F %N, @s zero.\n"),
666 /* i_fsize should be zero */
668 N_("i_fsize @F %N, @s zero.\n"),
671 /* inode has bad mode */
673 N_("@i %i (%Q) has a bad mode (%Im).\n"),
676 /* directory corrupted */
677 { PR_2_DIR_CORRUPTED,
678 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
681 /* filename too long */
682 { PR_2_FILENAME_LONG,
683 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
684 PROMPT_TRUNCATE, 0 },
686 /* Directory inode has a missing block (hole) */
687 { PR_2_DIRECTORY_HOLE,
688 N_("@d @i %i has an unallocated @b #%B. "),
689 PROMPT_ALLOCATE, 0 },
691 /* '.' is not NULL terminated */
692 { PR_2_DOT_NULL_TERM,
693 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
696 /* '..' is not NULL terminated */
697 { PR_2_DOT_DOT_NULL_TERM,
698 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
701 /* Illegal character device inode */
703 N_("@i %i (%Q) is an @I character device.\n"),
706 /* Illegal block device inode */
707 { PR_2_BAD_BLOCK_DEV,
708 N_("@i %i (%Q) is an @I @b device.\n"),
711 /* Duplicate '.' entry */
713 N_("@E is duplicate '.' @e.\n"),
716 /* Duplicate '..' entry */
718 N_("@E is duplicate '..' @e.\n"),
721 /* Internal error: couldn't find dir_info */
723 N_("Internal error: couldn't find dir_info for %i.\n"),
724 PROMPT_NONE, PR_FATAL },
726 /* Final rec_len is wrong */
728 N_("@E has rec_len of %dr, should be %N.\n"),
731 /* Error allocating icount structure */
732 { PR_2_ALLOCATE_ICOUNT,
733 N_("@A icount structure: %m\n"),
734 PROMPT_NONE, PR_FATAL },
736 /* Error iterating over directory blocks */
737 { PR_2_DBLIST_ITERATE,
738 N_("Error interating over @d @bs: %m\n"),
739 PROMPT_NONE, PR_FATAL },
741 /* Error reading directory block */
742 { PR_2_READ_DIRBLOCK,
743 N_("Error reading @d @b %b (@i %i): %m\n"),
744 PROMPT_CONTINUE, 0 },
746 /* Error writing directory block */
747 { PR_2_WRITE_DIRBLOCK,
748 N_("Error writing @d @b %b (@i %i): %m\n"),
749 PROMPT_CONTINUE, 0 },
751 /* Error allocating new directory block */
752 { PR_2_ALLOC_DIRBOCK,
753 N_("@A new @d @b for @i %i (%s): %m\n"),
756 /* Error deallocating inode */
757 { PR_2_DEALLOC_INODE,
758 N_("Error deallocating @i %i: %m\n"),
759 PROMPT_NONE, PR_FATAL },
761 /* Directory entry for '.' is big. Split? */
763 N_("@d @e for '.' is big. "),
764 PROMPT_SPLIT, PR_NO_OK },
766 /* Illegal FIFO inode */
768 N_("@i %i (%Q) is an @I FIFO.\n"),
771 /* Illegal socket inode */
773 N_("@i %i (%Q) is an @I socket.\n"),
776 /* Directory filetype not set */
778 N_("Setting filetype for @E to %N.\n"),
779 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
781 /* Directory filetype incorrect */
783 N_("@E has an incorrect filetype (was %dt, should be %N)\n"),
786 /* Directory filetype set on filesystem */
787 { PR_2_CLEAR_FILETYPE,
788 N_("@E has filetype set\n"),
789 PROMPT_CLEAR, PR_PREEN_OK },
791 /* Directory filename is null */
793 N_("@E has a zero-length name\n"),
798 /* Pass 3: Checking directory connectivity */
800 N_("Pass 3: Checking @d connectivity\n"),
803 /* Root inode not allocated */
804 { PR_3_NO_ROOT_INODE,
805 N_("@r not allocated. "),
806 PROMPT_ALLOCATE, 0 },
808 /* No room in lost+found */
809 { PR_3_EXPAND_LF_DIR,
810 N_("No room in @l @d. "),
813 /* Unconnected directory inode */
814 { PR_3_UNCONNECTED_DIR,
815 N_("Unconnected @d @i %i (%p)\n"),
818 /* /lost+found not found */
820 N_("/@l not found. "),
821 PROMPT_CREATE, PR_PREEN_OK },
823 /* .. entry is incorrect */
825 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
828 /* Bad or non-existent /lost+found. Cannot reconnect */
830 N_("Bad or non-existent /@l. Cannot reconnect\n"),
833 /* Could not expand /lost+found */
834 { PR_3_CANT_EXPAND_LPF,
835 N_("Could not expand /@l: %m\n"),
838 /* Could not reconnect inode */
839 { PR_3_CANT_RECONNECT,
840 N_("Could not reconnect %i: %m\n"),
843 /* Error while trying to find /lost+found */
845 N_("Error while trying to find /@l: %m\n"),
848 /* Error in ext2fs_new_block while creating /lost+found */
849 { PR_3_ERR_LPF_NEW_BLOCK,
850 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
853 /* Error in ext2fs_new_inode while creating /lost+found */
854 { PR_3_ERR_LPF_NEW_INODE,
855 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
858 /* Error in ext2fs_new_dir_block while creating /lost+found */
859 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
860 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
863 /* Error while writing directory block for /lost+found */
864 { PR_3_ERR_LPF_WRITE_BLOCK,
865 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
868 /* Error while adjusting inode count */
870 N_("Error while adjusting @i count on @i %i\n"),
873 /* Couldn't fix parent directory -- error */
874 { PR_3_FIX_PARENT_ERR,
875 N_("Couldn't fix parent of @i %i: %m\n\n"),
878 /* Couldn't fix parent directory -- couldn't find it */
879 { PR_3_FIX_PARENT_NOFIND,
880 N_("Couldn't fix parent of @i %i: Couldn't find parent @d entry\n\n"),
883 /* Error allocating inode bitmap */
884 { PR_3_ALLOCATE_IBITMAP_ERROR,
885 N_("@A @i @B (%N): %m\n"),
886 PROMPT_NONE, PR_FATAL },
888 /* Error creating root directory */
889 { PR_3_CREATE_ROOT_ERROR,
890 N_("Error creating root @d (%s): %m\n"),
891 PROMPT_NONE, PR_FATAL },
893 /* Error creating lost and found directory */
894 { PR_3_CREATE_LPF_ERROR,
895 N_("Error creating /@l @d (%s): %m\n"),
896 PROMPT_NONE, PR_FATAL },
898 /* Root inode is not directory; aborting */
899 { PR_3_ROOT_NOT_DIR_ABORT,
900 N_("@r is not a @d; aborting.\n"),
901 PROMPT_NONE, PR_FATAL },
903 /* Cannot proceed without a root inode. */
904 { PR_3_NO_ROOT_INODE_ABORT,
905 N_("Cannot proceed without a @r.\n"),
906 PROMPT_NONE, PR_FATAL },
908 /* Internal error: couldn't find dir_info */
910 N_("Internal error: couldn't find dir_info for %i.\n"),
911 PROMPT_NONE, PR_FATAL },
913 /* Lost+found not a directory */
915 N_("/@l is not a @d (ino=%i)\n"),
920 /* Pass 4: Checking reference counts */
922 N_("Pass 4: Checking reference counts\n"),
925 /* Unattached zero-length inode */
926 { PR_4_ZERO_LEN_INODE,
928 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
930 /* Unattached inode */
931 { PR_4_UNATTACHED_INODE,
935 /* Inode ref count wrong */
936 { PR_4_BAD_REF_COUNT,
937 N_("@i %i ref count is %Il, @s %N. "),
938 PROMPT_FIX, PR_PREEN_OK },
940 { PR_4_INCONSISTENT_COUNT,
941 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
942 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
943 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
944 "They should be the same!\n"),
949 /* Pass 5: Checking group summary information */
951 N_("Pass 5: Checking @g summary information\n"),
954 /* Padding at end of inode bitmap is not set. */
955 { PR_5_INODE_BMAP_PADDING,
956 N_("Padding at end of @i @B is not set. "),
957 PROMPT_FIX, PR_PREEN_OK },
959 /* Padding at end of block bitmap is not set. */
960 { PR_5_BLOCK_BMAP_PADDING,
961 N_("Padding at end of @b @B is not set. "),
962 PROMPT_FIX, PR_PREEN_OK },
964 /* Block bitmap differences header */
965 { PR_5_BLOCK_BITMAP_HEADER,
966 N_("@b @B differences: "),
967 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
969 /* Block not used, but marked in bitmap */
972 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
974 /* Block used, but not marked used in bitmap */
977 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
979 /* Block bitmap differences end */
980 { PR_5_BLOCK_BITMAP_END,
982 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
984 /* Inode bitmap differences header */
985 { PR_5_INODE_BITMAP_HEADER,
986 N_("@i @B differences: "),
987 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
989 /* Inode not used, but marked in bitmap */
992 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
994 /* Inode used, but not marked used in bitmap */
997 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
999 /* Inode bitmap differences end */
1000 { PR_5_INODE_BITMAP_END,
1002 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
1004 /* Free inodes count for group wrong */
1005 { PR_5_FREE_INODE_COUNT_GROUP,
1006 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
1007 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
1009 /* Directories count for group wrong */
1010 { PR_5_FREE_DIR_COUNT_GROUP,
1011 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
1012 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
1014 /* Free inodes count wrong */
1015 { PR_5_FREE_INODE_COUNT,
1016 N_("Free @is count wrong (%i, counted=%j).\n"),
1017 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
1019 /* Free blocks count for group wrong */
1020 { PR_5_FREE_BLOCK_COUNT_GROUP,
1021 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
1022 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
1024 /* Free blocks count wrong */
1025 { PR_5_FREE_BLOCK_COUNT,
1026 N_("Free @bs count wrong (%b, counted=%c).\n"),
1027 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
1029 /* Programming error: bitmap endpoints don't match */
1030 { PR_5_BMAP_ENDPOINTS,
1031 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
1032 "match calculated @B endpoints (%i, %j)\n"),
1033 PROMPT_NONE, PR_FATAL },
1035 /* Internal error: fudging end of bitmap */
1036 { PR_5_FUDGE_BITMAP_ERROR,
1037 N_("Internal error: fudging end of bitmap (%N)\n"),
1038 PROMPT_NONE, PR_FATAL },
1040 /* Error copying in replacement inode bitmap */
1041 { PR_5_COPY_IBITMAP_ERROR,
1042 "Error copying in replacement @i @B: %m\n",
1043 PROMPT_NONE, PR_FATAL },
1045 /* Error copying in replacement block bitmap */
1046 { PR_5_COPY_BBITMAP_ERROR,
1047 "Error copying in replacement @b @B: %m\n",
1048 PROMPT_NONE, PR_FATAL },
1054 * This is the latch flags register. It allows several problems to be
1055 * "latched" together. This means that the user has to answer but one
1056 * question for the set of problems, and all of the associated
1057 * problems will be either fixed or not fixed.
1059 static struct latch_descr pr_latch_info[] = {
1060 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
1061 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
1062 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
1063 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
1064 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
1065 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
1069 static const struct e2fsck_problem *find_problem(int code)
1073 for (i=0; problem_table[i].e2p_code; i++) {
1074 if (problem_table[i].e2p_code == code)
1075 return &problem_table[i];
1080 static struct latch_descr *find_latch(int code)
1084 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
1085 if (pr_latch_info[i].latch_code == code)
1086 return &pr_latch_info[i];
1091 int end_problem_latch(e2fsck_t ctx, int mask)
1093 struct latch_descr *ldesc;
1094 struct problem_context pctx;
1097 ldesc = find_latch(mask);
1098 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
1099 clear_problem_context(&pctx);
1100 answer = fix_problem(ctx, ldesc->end_message, &pctx);
1102 ldesc->flags &= ~(PRL_VARIABLE);
1106 int set_latch_flags(int mask, int setflags, int clearflags)
1108 struct latch_descr *ldesc;
1110 ldesc = find_latch(mask);
1113 ldesc->flags |= setflags;
1114 ldesc->flags &= ~clearflags;
1118 int get_latch_flags(int mask, int *value)
1120 struct latch_descr *ldesc;
1122 ldesc = find_latch(mask);
1125 *value = ldesc->flags;
1129 void clear_problem_context(struct problem_context *ctx)
1131 memset(ctx, 0, sizeof(struct problem_context));
1136 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
1138 ext2_filsys fs = ctx->fs;
1139 const struct e2fsck_problem *ptr;
1140 struct latch_descr *ldesc = 0;
1141 const char *message;
1142 int def_yn, answer, ans;
1143 int print_answer = 0;
1146 ptr = find_problem(code);
1148 printf(_("Unhandled error code (%d)!\n"), code);
1152 if ((ptr->flags & PR_NO_DEFAULT) ||
1153 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
1154 (ctx->options & E2F_OPT_NO))
1158 * Do special latch processing. This is where we ask the
1159 * latch question, if it exists
1161 if (ptr->flags & PR_LATCH_MASK) {
1162 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
1163 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
1164 ans = fix_problem(ctx, ldesc->question, pctx);
1166 ldesc->flags |= PRL_YES;
1168 ldesc->flags |= PRL_NO;
1169 ldesc->flags |= PRL_LATCHED;
1171 if (ldesc->flags & PRL_SUPPRESS)
1174 if ((ptr->flags & PR_PREEN_NOMSG) &&
1175 (ctx->options & E2F_OPT_PREEN))
1177 if ((ptr->flags & PR_NO_NOMSG) &&
1178 (ctx->options & E2F_OPT_NO))
1181 message = ptr->e2p_description;
1182 if (ctx->options & E2F_OPT_PREEN) {
1183 printf("%s: ", ctx->device_name);
1185 if (ptr->e2p_preen_msg)
1186 message = ptr->e2p_preen_msg;
1189 print_e2fsck_message(ctx, _(message), pctx, 1);
1191 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
1194 if (ptr->flags & PR_FATAL)
1195 fatal_error(ctx, 0);
1197 if (ptr->prompt == PROMPT_NONE) {
1198 if (ptr->flags & PR_NOCOLLATE)
1203 if (ctx->options & E2F_OPT_PREEN) {
1205 if (!(ptr->flags & PR_PREEN_NOMSG))
1207 } else if ((ptr->flags & PR_LATCH_MASK) &&
1208 (ldesc->flags & (PRL_YES | PRL_NO))) {
1211 if (ldesc->flags & PRL_YES)
1216 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
1217 if (!answer && !(ptr->flags & PR_NO_OK))
1218 ext2fs_unmark_valid(fs);
1221 printf("%s.\n", answer ?
1222 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
1226 if ((ptr->prompt == PROMPT_ABORT) && answer)
1227 fatal_error(ctx, 0);
1229 if (ptr->flags & PR_AFTER_CODE)
1230 answer = fix_problem(ctx, ptr->second_code, pctx);