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"),
175 /* Pass 1: Checking inodes, blocks, and sizes */
177 N_("Pass 1: Checking @is, @bs, and sizes\n"),
180 /* Root directory is not an inode */
181 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
184 /* Root directory has dtime set */
186 N_("@r has dtime set (probably due to old mke2fs). "),
187 PROMPT_FIX, PR_PREEN_OK },
189 /* Reserved inode has bad mode */
190 { PR_1_RESERVED_BAD_MODE,
191 N_("Reserved @i %i has bad mode. "),
192 PROMPT_CLEAR, PR_PREEN_OK },
194 /* Deleted inode has zero dtime */
196 N_("@D @i %i has zero dtime. "),
197 PROMPT_FIX, PR_PREEN_OK },
199 /* Inode in use, but dtime set */
201 N_("@i %i is in use, but has dtime set. "),
202 PROMPT_FIX, PR_PREEN_OK },
204 /* Zero-length directory */
205 { PR_1_ZERO_LENGTH_DIR,
206 N_("@i %i is a @z @d. "),
207 PROMPT_CLEAR, PR_PREEN_OK },
209 /* Block bitmap conflicts with some other fs block */
211 N_("@g %g's @b @B at %b @C.\n"),
212 PROMPT_RELOCATE, 0 },
214 /* Inode bitmap conflicts with some other fs block */
216 N_("@g %g's @i @B at %b @C.\n"),
217 PROMPT_RELOCATE, 0 },
219 /* Inode table conflicts with some other fs block */
220 { PR_1_ITABLE_CONFLICT,
221 N_("@g %g's @i table at %b @C.\n"),
222 PROMPT_RELOCATE, 0 },
224 /* Block bitmap is on a bad block */
226 N_("@g %g's @b @B (%b) is bad. "),
227 PROMPT_RELOCATE, 0 },
229 /* Inode bitmap is on a bad block */
231 N_("@g %g's @i @B (%b) is bad. "),
232 PROMPT_RELOCATE, 0 },
234 /* Inode has incorrect i_size */
236 N_("@i %i, i_size is %Is, @s %N. "),
237 PROMPT_FIX, PR_PREEN_OK },
239 /* Inode has incorrect i_blocks */
241 N_("@i %i, i_@bs is %Ib, @s %N. "),
242 PROMPT_FIX, PR_PREEN_OK },
244 /* Illegal block number in inode */
245 { PR_1_ILLEGAL_BLOCK_NUM,
246 N_("@I @b #%B (%b) in @i %i. "),
247 PROMPT_CLEAR, PR_LATCH_BLOCK },
249 /* Block number overlaps fs metadata */
250 { PR_1_BLOCK_OVERLAPS_METADATA,
251 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
252 PROMPT_CLEAR, PR_LATCH_BLOCK },
254 /* Inode has illegal blocks (latch question) */
255 { PR_1_INODE_BLOCK_LATCH,
256 N_("@i %i has illegal @b(s). "),
259 /* Too many bad blocks in inode */
260 { PR_1_TOO_MANY_BAD_BLOCKS,
261 N_("Too many illegal @bs in @i %i.\n"),
262 PROMPT_CLEAR_INODE, PR_NO_OK },
264 /* Illegal block number in bad block inode */
265 { PR_1_BB_ILLEGAL_BLOCK_NUM,
266 N_("@I @b #%B (%b) in bad @b @i. "),
267 PROMPT_CLEAR, PR_LATCH_BBLOCK },
269 /* Bad block inode has illegal blocks (latch question) */
270 { PR_1_INODE_BBLOCK_LATCH,
271 N_("Bad @b @i has illegal @b(s). "),
274 /* Duplicate or bad blocks in use! */
275 { PR_1_DUP_BLOCKS_PREENSTOP,
276 N_("Duplicate or bad @b in use!\n"),
279 /* Bad block used as bad block indirect block */
280 { PR_1_BBINODE_BAD_METABLOCK,
281 N_("Bad @b %b used as bad @b indirect @b?!?\n"),
282 PROMPT_NONE, PR_AFTER_CODE, PR_1_BBINODE_BAD_METABLOCK_PROMPT },
284 /* Inconsistency can't be fixed prompt */
285 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
286 N_("\nThis inconsistency can not be fixed with e2fsck; to fix it, use\n"
287 """dumpe2fs -b"" to dump out the bad @b "
288 "list and ""e2fsck -L filename""\n"
289 "to read it back in again.\n"),
290 PROMPT_CONTINUE, PR_PREEN_NOMSG },
292 /* Bad primary block */
293 { PR_1_BAD_PRIMARY_BLOCK,
294 N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
295 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
297 /* Bad primary block prompt */
298 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
299 N_("You can clear the this @b (and hope for the best) from the\n"
300 "bad @b list and hope that @b is really OK, but there are no\n"
302 PROMPT_CLEAR, PR_PREEN_NOMSG },
304 /* Bad primary superblock */
305 { PR_1_BAD_PRIMARY_SUPERBLOCK,
306 N_("The primary @S (%b) is on the bad @b list.\n"),
307 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
309 /* Bad primary block group descriptors */
310 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
311 N_("Block %b in the primary @g descriptors "
312 "is on the bad @b list\n"),
313 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
315 /* Bad superblock in group */
316 { PR_1_BAD_SUPERBLOCK,
317 N_("Warning: Group %g's @S (%b) is bad.\n"),
318 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
320 /* Bad block group descriptors in group */
321 { PR_1_BAD_GROUP_DESCRIPTORS,
322 N_("Warning: Group %g's copy of the @g descriptors has a bad "
324 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
326 /* Block claimed for no reason */
327 { PR_1_PROGERR_CLAIMED_BLOCK,
328 N_("Programming error? @b #%b claimed for no reason in "
329 "process_bad_@b.\n"),
330 PROMPT_NONE, PR_PREEN_OK },
332 /* Error allocating blocks for relocating metadata */
333 { PR_1_RELOC_BLOCK_ALLOCATE,
334 N_("@A %N @b(s) for %s: %m\n"),
335 PROMPT_NONE, PR_PREEN_OK },
337 /* Error allocating block buffer during relocation process */
338 { PR_1_RELOC_MEMORY_ALLOCATE,
339 N_("@A @b buffer for relocating %s\n"),
340 PROMPT_NONE, PR_PREEN_OK },
342 /* Relocating metadata group information from X to Y */
343 { PR_1_RELOC_FROM_TO,
344 N_("Relocating @g %g's %s from %b to %c...\n"),
345 PROMPT_NONE, PR_PREEN_OK },
347 /* Relocating metatdata group information to X */
349 N_("Relocating @g %g's %s to %c...\n"),
350 PROMPT_NONE, PR_PREEN_OK },
352 /* Block read error during relocation process */
353 { PR_1_RELOC_READ_ERR,
354 N_("Warning: could not read @b %b of %s: %m\n"),
355 PROMPT_NONE, PR_PREEN_OK },
357 /* Block write error during relocation process */
358 { PR_1_RELOC_WRITE_ERR,
359 N_("Warning: could not write @b %b for %s: %m\n"),
360 PROMPT_NONE, PR_PREEN_OK },
362 /* Error allocating inode bitmap */
363 { PR_1_ALLOCATE_IBITMAP_ERROR,
364 "@A @i @B (%N): %m\n",
365 PROMPT_NONE, PR_FATAL },
367 /* Error allocating block bitmap */
368 { PR_1_ALLOCATE_BBITMAP_ERROR,
369 "@A @b @B (%N): %m\n",
370 PROMPT_NONE, PR_FATAL },
372 /* Error allocating icount structure */
373 { PR_1_ALLOCATE_ICOUNT,
374 N_("@A icount link information: %m\n"),
375 PROMPT_NONE, PR_FATAL },
377 /* Error allocating dbcount */
378 { PR_1_ALLOCATE_DBCOUNT,
379 N_("@A @d @b array: %m\n"),
380 PROMPT_NONE, PR_FATAL },
382 /* Error while scanning inodes */
384 N_("Error while scanning @is (%i): %m\n"),
385 PROMPT_NONE, PR_FATAL },
387 /* Error while iterating over blocks */
388 { PR_1_BLOCK_ITERATE,
389 N_("Error while iterating over blocks in @i %i: %m\n"),
390 PROMPT_NONE, PR_FATAL },
392 /* Error while storing inode count information */
394 N_("Error storing @i count information (inode=%i, count=%N): %m\n"),
395 PROMPT_NONE, PR_FATAL },
397 /* Error while storing directory block information */
399 N_("Error storing @d @b information "
400 "(inode=%i, block=%b, num=%N): %m\n"),
401 PROMPT_NONE, PR_FATAL },
403 /* Error while reading inode (for clearing) */
405 N_("Error reading @i %i: %m\n"),
406 PROMPT_NONE, PR_FATAL },
408 /* Suppress messages prompt */
409 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
411 /* Filesystem contains large files, but has no such flag in sb */
412 { PR_1_FEATURE_LARGE_FILES,
413 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
416 /* Imagic flag set on an inode when filesystem doesn't support it */
418 N_("@i %i has imagic flag set. "),
421 /* Immutable flag set on a device or socket inode */
422 { PR_1_SET_IMMUTABLE,
423 N_("Special (device/socket/fifo) @i %i has immutable flag set. "),
424 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
426 /* Imagic flag set on an inode when filesystem doesn't support it */
428 N_("@i %i has @cion flag set on @f without @cion support. "),
433 /* Pass 1B: Rescan for duplicate/bad blocks */
435 N_("Duplicate @bs found... invoking duplicate @b passes.\n"
436 "Pass 1B: Rescan for duplicate/bad @bs\n"),
439 /* Duplicate/bad block(s) header */
440 { PR_1B_DUP_BLOCK_HEADER,
441 N_("Duplicate/bad @b(s) in @i %i:"),
444 /* Duplicate/bad block(s) in inode */
447 PROMPT_NONE, PR_LATCH_DBLOCK },
449 /* Duplicate/bad block(s) end */
450 { PR_1B_DUP_BLOCK_END,
454 /* Error while scanning inodes */
456 N_("Error while scanning inodes (%i): %m\n"),
457 PROMPT_NONE, PR_FATAL },
459 /* Error allocating inode bitmap */
460 { PR_1B_ALLOCATE_IBITMAP_ERROR,
461 N_("@A @i @B (inode_dup_map): %m\n"),
462 PROMPT_NONE, PR_FATAL },
465 /* Pass 1C: Scan directories for inodes with dup blocks. */
467 N_("Pass 1C: Scan directories for @is with dup @bs.\n"),
471 /* Pass 1D: Reconciling duplicate blocks */
473 N_("Pass 1D: Reconciling duplicate @bs\n"),
476 /* File has duplicate blocks */
478 N_("File %Q (@i #%i, mod time %IM) \n"
479 " has %B duplicate @b(s), shared with %N file(s):\n"),
482 /* List of files sharing duplicate blocks */
483 { PR_1D_DUP_FILE_LIST,
484 N_("\t%Q (@i #%i, mod time %IM)\n"),
487 /* File sharing blocks with filesystem metadata */
488 { PR_1D_SHARE_METADATA,
489 N_("\t<@f metadata>\n"),
492 /* Report of how many duplicate/bad inodes */
493 { PR_1D_NUM_DUP_INODES,
494 N_("(There are %N @is containing duplicate/bad @bs.)\n\n"),
497 /* Duplicated blocks already reassigned or cloned. */
498 { PR_1D_DUP_BLOCKS_DEALT,
499 N_("Duplicated @bs already reassigned or cloned.\n\n"),
502 /* Clone duplicate/bad blocks? */
503 { PR_1D_CLONE_QUESTION,
504 "", PROMPT_CLONE, PR_NO_OK },
507 { PR_1D_DELETE_QUESTION,
508 "", PROMPT_DELETE, 0 },
510 /* Couldn't clone file (error) */
512 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
516 /* Pass 2: Checking directory structure */
518 N_("Pass 2: Checking @d structure\n"),
521 /* Bad inode number for '.' */
522 { PR_2_BAD_INODE_DOT,
523 N_("Bad @i number for '.' in @d @i %i.\n"),
526 /* Directory entry has bad inode number */
528 N_("@E has bad @i #: %Di.\n"),
531 /* Directory entry has deleted or unused inode */
533 N_("@E has @D/unused @i %Di. "),
534 PROMPT_CLEAR, PR_PREEN_OK },
536 /* Directry entry is link to '.' */
541 /* Directory entry points to inode now located in a bad block */
543 N_("@E points to @i (%Di) located in a bad @b.\n"),
546 /* Directory entry contains a link to a directory */
548 N_("@E @L to @d %P (%Di).\n"),
551 /* Directory entry contains a link to the root directry */
553 N_("@E @L to the @r.\n"),
556 /* Directory entry has illegal characters in its name */
558 N_("@E has illegal characters in its name.\n"),
561 /* Missing '.' in directory inode */
563 N_("Missing '.' in @d @i %i.\n"),
566 /* Missing '..' in directory inode */
567 { PR_2_MISSING_DOT_DOT,
568 N_("Missing '..' in @d @i %i.\n"),
571 /* First entry in directory inode doesn't contain '.' */
573 N_("First @e '%Dn' (inode=%Di) in @d @i %i (%p) @s '.'\n"),
576 /* Second entry in directory inode doesn't contain '..' */
577 { PR_2_2ND_NOT_DOT_DOT,
578 N_("Second @e '%Dn' (inode=%Di) in @d @i %i @s '..'\n"),
581 /* i_faddr should be zero */
583 N_("i_faddr @F %IF, @s zero.\n"),
586 /* i_file_acl should be zero */
587 { PR_2_FILE_ACL_ZERO,
588 N_("i_file_acl @F %If, @s zero.\n"),
591 /* i_dir_acl should be zero */
593 N_("i_dir_acl @F %Id, @s zero.\n"),
596 /* i_frag should be zero */
598 N_("i_frag @F %N, @s zero.\n"),
601 /* i_fsize should be zero */
603 N_("i_fsize @F %N, @s zero.\n"),
606 /* inode has bad mode */
608 N_("@i %i (%Q) has a bad mode (%Im).\n"),
611 /* directory corrupted */
612 { PR_2_DIR_CORRUPTED,
613 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
616 /* filename too long */
617 { PR_2_FILENAME_LONG,
618 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
619 PROMPT_TRUNCATE, 0 },
621 /* Directory inode has a missing block (hole) */
622 { PR_2_DIRECTORY_HOLE,
623 N_("@d @i %i has an unallocated @b #%B. "),
624 PROMPT_ALLOCATE, 0 },
626 /* '.' is not NULL terminated */
627 { PR_2_DOT_NULL_TERM,
628 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
631 /* '..' is not NULL terminated */
632 { PR_2_DOT_DOT_NULL_TERM,
633 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
636 /* Illegal character device inode */
638 N_("@i %i (%Q) is an @I character device.\n"),
641 /* Illegal block device inode */
642 { PR_2_BAD_BLOCK_DEV,
643 N_("@i %i (%Q) is an @I @b device.\n"),
646 /* Duplicate '.' entry */
648 N_("@E is duplicate '.' @e.\n"),
651 /* Duplicate '..' entry */
653 N_("@E is duplicate '..' @e.\n"),
656 /* Internal error: couldn't find dir_info */
658 N_("Internal error: couldn't find dir_info for %i.\n"),
659 PROMPT_NONE, PR_FATAL },
661 /* Final rec_len is wrong */
663 N_("@E has rec_len of %dr, should be %N.\n"),
666 /* Error allocating icount structure */
667 { PR_2_ALLOCATE_ICOUNT,
668 N_("@A icount structure: %m\n"),
669 PROMPT_NONE, PR_FATAL },
671 /* Error iterating over directory blocks */
672 { PR_2_DBLIST_ITERATE,
673 N_("Error interating over @d @bs: %m\n"),
674 PROMPT_NONE, PR_FATAL },
676 /* Error reading directory block */
677 { PR_2_READ_DIRBLOCK,
678 N_("Error reading @d @b %b (@i %i): %m\n"),
679 PROMPT_CONTINUE, 0 },
681 /* Error writing directory block */
682 { PR_2_WRITE_DIRBLOCK,
683 N_("Error writing @d @b %b (@i %i): %m\n"),
684 PROMPT_CONTINUE, 0 },
686 /* Error allocating new directory block */
687 { PR_2_ALLOC_DIRBOCK,
688 N_("@A new @d @b for @i %i (%s): %m\n"),
691 /* Error deallocating inode */
692 { PR_2_DEALLOC_INODE,
693 N_("Error deallocating @i %i: %m\n"),
694 PROMPT_NONE, PR_FATAL },
696 /* Directory entry for '.' is big. Split? */
698 N_("@d @e for '.' is big. "),
699 PROMPT_SPLIT, PR_NO_OK },
701 /* Illegal FIFO inode */
703 N_("@i %i (%Q) is an @I FIFO.\n"),
706 /* Illegal socket inode */
708 N_("@i %i (%Q) is an @I socket.\n"),
711 /* Directory filetype not set */
713 N_("Setting filetype for @E to %N.\n"),
714 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
716 /* Directory filetype incorrect */
718 N_("@E has an incorrect filetype (was %dt, should be %N)\n"),
721 /* Directory filetype set on filesystem */
722 { PR_2_CLEAR_FILETYPE,
723 N_("@E has filetype set\n"),
724 PROMPT_CLEAR, PR_PREEN_OK },
726 /* Directory filename is null */
728 N_("@E has a zero-length name\n"),
733 /* Pass 3: Checking directory connectivity */
735 N_("Pass 3: Checking @d connectivity\n"),
738 /* Root inode not allocated */
739 { PR_3_NO_ROOT_INODE,
740 N_("@r not allocated. "),
741 PROMPT_ALLOCATE, 0 },
743 /* No room in lost+found */
744 { PR_3_EXPAND_LF_DIR,
745 N_("No room in @l @d. "),
748 /* Unconnected directory inode */
749 { PR_3_UNCONNECTED_DIR,
750 N_("Unconnected @d @i %i (%p)\n"),
753 /* /lost+found not found */
755 N_("/@l not found. "),
756 PROMPT_CREATE, PR_PREEN_OK },
758 /* .. entry is incorrect */
760 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
763 /* Bad or non-existent /lost+found. Cannot reconnect */
765 N_("Bad or non-existent /@l. Cannot reconnect\n"),
768 /* Could not expand /lost+found */
769 { PR_3_CANT_EXPAND_LPF,
770 N_("Could not expand /@l: %m\n"),
773 /* Could not reconnect inode */
774 { PR_3_CANT_RECONNECT,
775 N_("Could not reconnect %i: %m\n"),
778 /* Error while trying to find /lost+found */
780 N_("Error while trying to find /@l: %m\n"),
783 /* Error in ext2fs_new_block while creating /lost+found */
784 { PR_3_ERR_LPF_NEW_BLOCK,
785 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
788 /* Error in ext2fs_new_inode while creating /lost+found */
789 { PR_3_ERR_LPF_NEW_INODE,
790 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
793 /* Error in ext2fs_new_dir_block while creating /lost+found */
794 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
795 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
798 /* Error while writing directory block for /lost+found */
799 { PR_3_ERR_LPF_WRITE_BLOCK,
800 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
803 /* Error while adjusting inode count */
805 N_("Error while adjusting @i count on @i %i\n"),
808 /* Couldn't fix parent directory -- error */
809 { PR_3_FIX_PARENT_ERR,
810 N_("Couldn't fix parent of @i %i: %m\n\n"),
813 /* Couldn't fix parent directory -- couldn't find it */
814 { PR_3_FIX_PARENT_NOFIND,
815 N_("Couldn't fix parent of @i %i: Couldn't find parent @d entry\n\n"),
818 /* Error allocating inode bitmap */
819 { PR_3_ALLOCATE_IBITMAP_ERROR,
820 N_("@A @i @B (%N): %m\n"),
821 PROMPT_NONE, PR_FATAL },
823 /* Error creating root directory */
824 { PR_3_CREATE_ROOT_ERROR,
825 N_("Error creating root @d (%s): %m\n"),
826 PROMPT_NONE, PR_FATAL },
828 /* Error creating lost and found directory */
829 { PR_3_CREATE_LPF_ERROR,
830 N_("Error creating /@l @d (%s): %m\n"),
831 PROMPT_NONE, PR_FATAL },
833 /* Root inode is not directory; aborting */
834 { PR_3_ROOT_NOT_DIR_ABORT,
835 N_("@r is not a @d; aborting.\n"),
836 PROMPT_NONE, PR_FATAL },
838 /* Cannot proceed without a root inode. */
839 { PR_3_NO_ROOT_INODE_ABORT,
840 N_("Cannot proceed without a @r.\n"),
841 PROMPT_NONE, PR_FATAL },
843 /* Internal error: couldn't find dir_info */
845 N_("Internal error: couldn't find dir_info for %i.\n"),
846 PROMPT_NONE, PR_FATAL },
848 /* Lost+found not a directory */
850 N_("/@l is not a @d (ino=%i)\n"),
855 /* Pass 4: Checking reference counts */
857 N_("Pass 4: Checking reference counts\n"),
860 /* Unattached zero-length inode */
861 { PR_4_ZERO_LEN_INODE,
863 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
865 /* Unattached inode */
866 { PR_4_UNATTACHED_INODE,
870 /* Inode ref count wrong */
871 { PR_4_BAD_REF_COUNT,
872 N_("@i %i ref count is %Il, @s %N. "),
873 PROMPT_FIX, PR_PREEN_OK },
875 { PR_4_INCONSISTENT_COUNT,
876 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
877 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
878 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
879 "They should be the same!\n"),
884 /* Pass 5: Checking group summary information */
886 N_("Pass 5: Checking @g summary information\n"),
889 /* Padding at end of inode bitmap is not set. */
890 { PR_5_INODE_BMAP_PADDING,
891 N_("Padding at end of @i @B is not set. "),
892 PROMPT_FIX, PR_PREEN_OK },
894 /* Padding at end of block bitmap is not set. */
895 { PR_5_BLOCK_BMAP_PADDING,
896 N_("Padding at end of @b @B is not set. "),
897 PROMPT_FIX, PR_PREEN_OK },
899 /* Block bitmap differences header */
900 { PR_5_BLOCK_BITMAP_HEADER,
901 N_("@b @B differences: "),
902 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
904 /* Block not used, but marked in bitmap */
907 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
909 /* Block used, but not marked used in bitmap */
912 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
914 /* Block bitmap differences end */
915 { PR_5_BLOCK_BITMAP_END,
917 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
919 /* Inode bitmap differences header */
920 { PR_5_INODE_BITMAP_HEADER,
921 N_("@i @B differences: "),
922 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
924 /* Inode not used, but marked in bitmap */
927 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
929 /* Inode used, but not marked used in bitmap */
932 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
934 /* Inode bitmap differences end */
935 { PR_5_INODE_BITMAP_END,
937 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
939 /* Free inodes count for group wrong */
940 { PR_5_FREE_INODE_COUNT_GROUP,
941 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
942 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
944 /* Directories count for group wrong */
945 { PR_5_FREE_DIR_COUNT_GROUP,
946 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
947 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
949 /* Free inodes count wrong */
950 { PR_5_FREE_INODE_COUNT,
951 N_("Free @is count wrong (%i, counted=%j).\n"),
952 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
954 /* Free blocks count for group wrong */
955 { PR_5_FREE_BLOCK_COUNT_GROUP,
956 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
957 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
959 /* Free blocks count wrong */
960 { PR_5_FREE_BLOCK_COUNT,
961 N_("Free @bs count wrong (%b, counted=%c).\n"),
962 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
964 /* Programming error: bitmap endpoints don't match */
965 { PR_5_BMAP_ENDPOINTS,
966 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
967 "match calculated @B endpoints (%i, %j)\n"),
968 PROMPT_NONE, PR_FATAL },
970 /* Internal error: fudging end of bitmap */
971 { PR_5_FUDGE_BITMAP_ERROR,
972 N_("Internal error: fudging end of bitmap (%N)\n"),
973 PROMPT_NONE, PR_FATAL },
979 * This is the latch flags register. It allows several problems to be
980 * "latched" together. This means that the user has to answer but one
981 * question for the set of problems, and all of the associated
982 * problems will be either fixed or not fixed.
984 static struct latch_descr pr_latch_info[] = {
985 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
986 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
987 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
988 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
989 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
990 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
994 static const struct e2fsck_problem *find_problem(int code)
998 for (i=0; problem_table[i].e2p_code; i++) {
999 if (problem_table[i].e2p_code == code)
1000 return &problem_table[i];
1005 static struct latch_descr *find_latch(int code)
1009 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
1010 if (pr_latch_info[i].latch_code == code)
1011 return &pr_latch_info[i];
1016 int end_problem_latch(e2fsck_t ctx, int mask)
1018 struct latch_descr *ldesc;
1019 struct problem_context pctx;
1022 ldesc = find_latch(mask);
1023 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
1024 clear_problem_context(&pctx);
1025 answer = fix_problem(ctx, ldesc->end_message, &pctx);
1027 ldesc->flags &= ~(PRL_VARIABLE);
1031 int set_latch_flags(int mask, int setflags, int clearflags)
1033 struct latch_descr *ldesc;
1035 ldesc = find_latch(mask);
1038 ldesc->flags |= setflags;
1039 ldesc->flags &= ~clearflags;
1043 int get_latch_flags(int mask, int *value)
1045 struct latch_descr *ldesc;
1047 ldesc = find_latch(mask);
1050 *value = ldesc->flags;
1054 void clear_problem_context(struct problem_context *ctx)
1056 memset(ctx, 0, sizeof(struct problem_context));
1061 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
1063 ext2_filsys fs = ctx->fs;
1064 const struct e2fsck_problem *ptr;
1065 struct latch_descr *ldesc = 0;
1066 const char *message;
1067 int def_yn, answer, ans;
1068 int print_answer = 0;
1071 ptr = find_problem(code);
1073 printf(_("Unhandled error code (%d)!\n"), code);
1077 if ((ptr->flags & PR_NO_DEFAULT) ||
1078 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
1079 (ctx->options & E2F_OPT_NO))
1083 * Do special latch processing. This is where we ask the
1084 * latch question, if it exists
1086 if (ptr->flags & PR_LATCH_MASK) {
1087 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
1088 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
1089 ans = fix_problem(ctx, ldesc->question, pctx);
1091 ldesc->flags |= PRL_YES;
1093 ldesc->flags |= PRL_NO;
1094 ldesc->flags |= PRL_LATCHED;
1096 if (ldesc->flags & PRL_SUPPRESS)
1099 if ((ptr->flags & PR_PREEN_NOMSG) &&
1100 (ctx->options & E2F_OPT_PREEN))
1102 if ((ptr->flags & PR_NO_NOMSG) &&
1103 (ctx->options & E2F_OPT_NO))
1106 message = ptr->e2p_description;
1107 if (ctx->options & E2F_OPT_PREEN) {
1108 printf("%s: ", ctx->device_name);
1110 if (ptr->e2p_preen_msg)
1111 message = ptr->e2p_preen_msg;
1114 print_e2fsck_message(ctx, _(message), pctx, 1);
1116 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
1119 if (ptr->flags & PR_FATAL)
1120 fatal_error(ctx, 0);
1122 if (ptr->prompt == PROMPT_NONE) {
1123 if (ptr->flags & PR_NOCOLLATE)
1128 if (ctx->options & E2F_OPT_PREEN) {
1130 if (!(ptr->flags & PR_PREEN_NOMSG))
1132 } else if ((ptr->flags & PR_LATCH_MASK) &&
1133 (ldesc->flags & (PRL_YES | PRL_NO))) {
1136 if (ldesc->flags & PRL_YES)
1141 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
1142 if (!answer && !(ptr->flags & PR_NO_OK))
1143 ext2fs_unmark_valid(fs);
1146 printf("%s.\n", answer ?
1147 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
1151 if (ptr->flags & PR_AFTER_CODE)
1152 (void) fix_problem(ctx, ptr->second_code, pctx);
1154 if ((ptr->prompt == PROMPT_ABORT) && answer)
1155 fatal_error(ctx, 0);