problem.c revision c7f23364fd6d8d25d74e51ba5f342fc2230048d8
1/* 2 * problem.c --- report filesystem problems to the user 3 * 4 * Copyright 1996, 1997 by Theodore Ts'o 5 * 6 * %Begin-Header% 7 * This file may be redistributed under the terms of the GNU Public 8 * License. 9 * %End-Header% 10 */ 11 12#include <stdlib.h> 13#include <unistd.h> 14#include <string.h> 15#include <ctype.h> 16#include <termios.h> 17 18#include "e2fsck.h" 19 20#include "problem.h" 21#include "problemP.h" 22 23#define PROMPT_NONE 0 24#define PROMPT_FIX 1 25#define PROMPT_CLEAR 2 26#define PROMPT_RELOCATE 3 27#define PROMPT_ALLOCATE 4 28#define PROMPT_EXPAND 5 29#define PROMPT_CONNECT 6 30#define PROMPT_CREATE 7 31#define PROMPT_SALVAGE 8 32#define PROMPT_TRUNCATE 9 33#define PROMPT_CLEAR_INODE 10 34#define PROMPT_ABORT 11 35#define PROMPT_SPLIT 12 36#define PROMPT_CONTINUE 13 37#define PROMPT_CLONE 14 38#define PROMPT_DELETE 15 39#define PROMPT_SUPPRESS 16 40#define PROMPT_UNLINK 17 41 42/* 43 * These are the prompts which are used to ask the user if they want 44 * to fix a problem. 45 */ 46static const char *prompt[] = { 47 N_("(no prompt)"), /* 0 */ 48 N_("Fix"), /* 1 */ 49 N_("Clear"), /* 2 */ 50 N_("Relocate"), /* 3 */ 51 N_("Allocate"), /* 4 */ 52 N_("Expand"), /* 5 */ 53 N_("Connect to /lost+found"), /* 6 */ 54 N_("Create"), /* 7 */ 55 N_("Salvage"), /* 8 */ 56 N_("Truncate"), /* 9 */ 57 N_("Clear inode"), /* 10 */ 58 N_("Abort"), /* 11 */ 59 N_("Split"), /* 12 */ 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 */ 65}; 66 67/* 68 * These messages are printed when we are preen mode and we will be 69 * automatically fixing the problem. 70 */ 71static const char *preen_msg[] = { 72 N_("(NONE)"), /* 0 */ 73 N_("FIXED"), /* 1 */ 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 */ 84 N_("SPLIT"), /* 12 */ 85 N_("CONTINUING"), /* 13 */ 86 N_("DUPLICATE/BAD BLOCKS CLONED"), /* 14 */ 87 N_("FILE DELETED"), /* 15 */ 88 N_("SUPPRESSED"), /* 16 */ 89 N_("UNLINKED"), /* 17 */ 90}; 91 92static const struct e2fsck_problem problem_table[] = { 93 94 /* Pre-Pass 1 errors */ 95 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 }, 99 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 }, 103 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 }, 109 110 /* Superblock corrupt */ 111 { PR_0_SB_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 }, 118 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"), 124 PROMPT_ABORT, 0 }, 125 126 /* Fragments not supported */ 127 { PR_0_NO_FRAGMENTS, 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 }, 132 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 }, 137 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 }, 142 143 /* Adding UUID to filesystem */ 144 { PR_0_ADD_UUID, 145 N_("@f did not have a UUID; generating one.\n\n"), 146 PROMPT_NONE, 0 }, 147 148 /* Relocate hint */ 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 }, 157 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 }, 162 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 }, 167 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"), 171 PROMPT_FIX, 0 }, 172 173 { PR_0_HURD_CLEAR_FILETYPE, 174 N_("The Hurd does not support the filetype feature.\n"), 175 PROMPT_CLEAR, 0 }, 176 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 }, 181 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 }, 186 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 }, 191 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 }, 196 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 }, 201 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 "It is likely that your copy of e2fsck is old and/or doesn't " 206 "support this @j format.\n" 207 "It is also possible the @j @S is corrupt.\n"), 208 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER }, 209 210 /* Journal superblock is corrupt */ 211 { PR_0_JOURNAL_BAD_SUPER, 212 N_("Ext3 @j @S is corrupt.\n"), 213 PROMPT_FIX, PR_PREEN_OK }, 214 215 /* Superblock flag should be cleared */ 216 { PR_0_JOURNAL_HAS_JOURNAL, 217 N_("@S doesn't have has_journal flag, but has ext3 @j %s.\n"), 218 PROMPT_CLEAR, PR_PREEN_OK }, 219 220 /* Superblock flag is incorrect */ 221 { PR_0_JOURNAL_RECOVER_SET, 222 N_("@S has ext3 needs_recovery flag set, but no @j.\n"), 223 PROMPT_CLEAR, PR_PREEN_OK }, 224 225 /* Journal should be reset */ 226 { PR_0_JOURNAL_RESET_JOURNAL, 227 N_("*** WARNING *** leaving data in the @j may be DANGEROUS.\n"), 228 PROMPT_NONE, PR_PREEN_NOMSG|PR_AFTER_CODE, PR_0_JOURNAL_RESET_PROMPT}, 229 230 /* Journal should be reset */ 231 { PR_0_JOURNAL_RESET_PROMPT, 232 N_("ext3 recovery flag clear, but journal has data.\n"), 233 PROMPT_CLEAR, PR_PREEN_OK|PR_PREEN_NOMSG }, 234 235 /* Clearing orphan inode */ 236 { PR_0_ORPHAN_CLEAR_INODE, 237 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"), 238 PROMPT_NONE, 0 }, 239 240 /* Illegal block found in orphaned inode */ 241 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, 242 N_("@I @b #%B (%b) found in @o @i %i.\n"), 243 PROMPT_NONE, 0 }, 244 245 /* Already cleared block found in orphaned inode */ 246 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, 247 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"), 248 PROMPT_NONE, 0 }, 249 250 /* Illegal orphan inode in superblock */ 251 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE, 252 N_("@I @o @i %i in @S.\n"), 253 PROMPT_NONE, 0 }, 254 255 /* Illegal inode in orphaned inode list */ 256 { PR_0_ORPHAN_ILLEGAL_INODE, 257 N_("@I @i %i in @o @i list.\n"), 258 PROMPT_NONE, 0 }, 259 260 /* Filesystem revision is 0, but feature flags are set */ 261 { PR_0_FS_REV_LEVEL, 262 "@f has feature flag(s) set, but is a revision 0 @f. ", 263 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK }, 264 265 /* Journal superblock has an unknown read-only feature flag set */ 266 { PR_0_JOURNAL_UNSUPP_ROCOMPAT, 267 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"), 268 PROMPT_NONE, PR_FATAL, PR_0_JOURNAL_RESET_COMPAT }, 269 270 /* Journal superblock has an unknown incompatible feature flag set */ 271 { PR_0_JOURNAL_UNSUPP_INCOMPAT, 272 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"), 273 PROMPT_NONE, PR_FATAL, PR_0_JOURNAL_RESET_COMPAT }, 274 275 /* Journal superblock has an unknown feature flag set */ 276 { PR_0_JOURNAL_RESET_COMPAT, 277 N_("Ext3 @j @S has bad feature flag(s) set.\n"), 278 PROMPT_CLEAR, PR_PREEN_OK|PR_PREEN_NOMSG }, 279 280 /* Journal has unsupported version number */ 281 { PR_0_JOURNAL_UNSUPP_VERSION, 282 N_("@j version not supported by this e2fsck.\n"), 283 PROMPT_ABORT, 0 }, 284 285 /* Pass 1 errors */ 286 287 /* Pass 1: Checking inodes, blocks, and sizes */ 288 { PR_1_PASS_HEADER, 289 N_("Pass 1: Checking @is, @bs, and sizes\n"), 290 PROMPT_NONE, 0 }, 291 292 /* Root directory is not an inode */ 293 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "), 294 PROMPT_CLEAR, 0 }, 295 296 /* Root directory has dtime set */ 297 { PR_1_ROOT_DTIME, 298 N_("@r has dtime set (probably due to old mke2fs). "), 299 PROMPT_FIX, PR_PREEN_OK }, 300 301 /* Reserved inode has bad mode */ 302 { PR_1_RESERVED_BAD_MODE, 303 N_("Reserved @i %i %Q has bad mode. "), 304 PROMPT_CLEAR, PR_PREEN_OK }, 305 306 /* Deleted inode has zero dtime */ 307 { PR_1_ZERO_DTIME, 308 N_("@D @i %i has zero dtime. "), 309 PROMPT_FIX, PR_PREEN_OK }, 310 311 /* Inode in use, but dtime set */ 312 { PR_1_SET_DTIME, 313 N_("@i %i is in use, but has dtime set. "), 314 PROMPT_FIX, PR_PREEN_OK }, 315 316 /* Zero-length directory */ 317 { PR_1_ZERO_LENGTH_DIR, 318 N_("@i %i is a @z @d. "), 319 PROMPT_CLEAR, PR_PREEN_OK }, 320 321 /* Block bitmap conflicts with some other fs block */ 322 { PR_1_BB_CONFLICT, 323 N_("@g %g's @b @B at %b @C.\n"), 324 PROMPT_RELOCATE, 0 }, 325 326 /* Inode bitmap conflicts with some other fs block */ 327 { PR_1_IB_CONFLICT, 328 N_("@g %g's @i @B at %b @C.\n"), 329 PROMPT_RELOCATE, 0 }, 330 331 /* Inode table conflicts with some other fs block */ 332 { PR_1_ITABLE_CONFLICT, 333 N_("@g %g's @i table at %b @C.\n"), 334 PROMPT_RELOCATE, 0 }, 335 336 /* Block bitmap is on a bad block */ 337 { PR_1_BB_BAD_BLOCK, 338 N_("@g %g's @b @B (%b) is bad. "), 339 PROMPT_RELOCATE, 0 }, 340 341 /* Inode bitmap is on a bad block */ 342 { PR_1_IB_BAD_BLOCK, 343 N_("@g %g's @i @B (%b) is bad. "), 344 PROMPT_RELOCATE, 0 }, 345 346 /* Inode has incorrect i_size */ 347 { PR_1_BAD_I_SIZE, 348 N_("@i %i, i_size is %Is, @s %N. "), 349 PROMPT_FIX, PR_PREEN_OK }, 350 351 /* Inode has incorrect i_blocks */ 352 { PR_1_BAD_I_BLOCKS, 353 N_("@i %i, i_@bs is %Ib, @s %N. "), 354 PROMPT_FIX, PR_PREEN_OK }, 355 356 /* Illegal blocknumber in inode */ 357 { PR_1_ILLEGAL_BLOCK_NUM, 358 N_("@I @b #%B (%b) in @i %i. "), 359 PROMPT_CLEAR, PR_LATCH_BLOCK }, 360 361 /* Block number overlaps fs metadata */ 362 { PR_1_BLOCK_OVERLAPS_METADATA, 363 N_("@b #%B (%b) overlaps @f metadata in @i %i. "), 364 PROMPT_CLEAR, PR_LATCH_BLOCK }, 365 366 /* Inode has illegal blocks (latch question) */ 367 { PR_1_INODE_BLOCK_LATCH, 368 N_("@i %i has illegal @b(s). "), 369 PROMPT_CLEAR, 0 }, 370 371 /* Too many bad blocks in inode */ 372 { PR_1_TOO_MANY_BAD_BLOCKS, 373 N_("Too many illegal @bs in @i %i.\n"), 374 PROMPT_CLEAR_INODE, PR_NO_OK }, 375 376 /* Illegal block number in bad block inode */ 377 { PR_1_BB_ILLEGAL_BLOCK_NUM, 378 N_("@I @b #%B (%b) in bad @b @i. "), 379 PROMPT_CLEAR, PR_LATCH_BBLOCK }, 380 381 /* Bad block inode has illegal blocks (latch question) */ 382 { PR_1_INODE_BBLOCK_LATCH, 383 N_("Bad @b @i has illegal @b(s). "), 384 PROMPT_CLEAR, 0 }, 385 386 /* Duplicate or bad blocks in use! */ 387 { PR_1_DUP_BLOCKS_PREENSTOP, 388 N_("Duplicate or bad @b in use!\n"), 389 PROMPT_NONE, 0 }, 390 391 /* Bad block used as bad block indirect block */ 392 { PR_1_BBINODE_BAD_METABLOCK, 393 N_("Bad @b %b used as bad @b indirect @b?!?\n"), 394 PROMPT_NONE, PR_AFTER_CODE, PR_1_BBINODE_BAD_METABLOCK_PROMPT }, 395 396 /* Inconsistency can't be fixed prompt */ 397 { PR_1_BBINODE_BAD_METABLOCK_PROMPT, 398 N_("\nThis inconsistency can not be fixed with e2fsck; to fix it, use\n" 399 """dumpe2fs -b"" to dump out the bad @b " 400 "list and ""e2fsck -L filename""\n" 401 "to read it back in again.\n"), 402 PROMPT_CONTINUE, PR_PREEN_NOMSG }, 403 404 /* Bad primary block */ 405 { PR_1_BAD_PRIMARY_BLOCK, 406 N_("\nIf the @b is really bad, the @f can not be fixed.\n"), 407 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT }, 408 409 /* Bad primary block prompt */ 410 { PR_1_BAD_PRIMARY_BLOCK_PROMPT, 411 N_("You can clear the this @b (and hope for the best) from the\n" 412 "bad @b list and hope that @b is really OK, but there are no\n" 413 "guarantees.\n\n"), 414 PROMPT_CLEAR, PR_PREEN_NOMSG }, 415 416 /* Bad primary superblock */ 417 { PR_1_BAD_PRIMARY_SUPERBLOCK, 418 N_("The primary @S (%b) is on the bad @b list.\n"), 419 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK }, 420 421 /* Bad primary block group descriptors */ 422 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, 423 N_("Block %b in the primary @g descriptors " 424 "is on the bad @b list\n"), 425 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK }, 426 427 /* Bad superblock in group */ 428 { PR_1_BAD_SUPERBLOCK, 429 N_("Warning: Group %g's @S (%b) is bad.\n"), 430 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG }, 431 432 /* Bad block group descriptors in group */ 433 { PR_1_BAD_GROUP_DESCRIPTORS, 434 N_("Warning: Group %g's copy of the @g descriptors has a bad " 435 "@b (%b).\n"), 436 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG }, 437 438 /* Block claimed for no reason */ 439 { PR_1_PROGERR_CLAIMED_BLOCK, 440 N_("Programming error? @b #%b claimed for no reason in " 441 "process_bad_@b.\n"), 442 PROMPT_NONE, PR_PREEN_OK }, 443 444 /* Error allocating blocks for relocating metadata */ 445 { PR_1_RELOC_BLOCK_ALLOCATE, 446 N_("@A %N @b(s) for %s: %m\n"), 447 PROMPT_NONE, PR_PREEN_OK }, 448 449 /* Error allocating block buffer during relocation process */ 450 { PR_1_RELOC_MEMORY_ALLOCATE, 451 N_("@A @b buffer for relocating %s\n"), 452 PROMPT_NONE, PR_PREEN_OK }, 453 454 /* Relocating metadata group information from X to Y */ 455 { PR_1_RELOC_FROM_TO, 456 N_("Relocating @g %g's %s from %b to %c...\n"), 457 PROMPT_NONE, PR_PREEN_OK }, 458 459 /* Relocating metatdata group information to X */ 460 { PR_1_RELOC_TO, 461 N_("Relocating @g %g's %s to %c...\n"), 462 PROMPT_NONE, PR_PREEN_OK }, 463 464 /* Block read error during relocation process */ 465 { PR_1_RELOC_READ_ERR, 466 N_("Warning: could not read @b %b of %s: %m\n"), 467 PROMPT_NONE, PR_PREEN_OK }, 468 469 /* Block write error during relocation process */ 470 { PR_1_RELOC_WRITE_ERR, 471 N_("Warning: could not write @b %b for %s: %m\n"), 472 PROMPT_NONE, PR_PREEN_OK }, 473 474 /* Error allocating inode bitmap */ 475 { PR_1_ALLOCATE_IBITMAP_ERROR, 476 "@A @i @B (%N): %m\n", 477 PROMPT_NONE, PR_FATAL }, 478 479 /* Error allocating block bitmap */ 480 { PR_1_ALLOCATE_BBITMAP_ERROR, 481 "@A @b @B (%N): %m\n", 482 PROMPT_NONE, PR_FATAL }, 483 484 /* Error allocating icount structure */ 485 { PR_1_ALLOCATE_ICOUNT, 486 N_("@A icount link information: %m\n"), 487 PROMPT_NONE, PR_FATAL }, 488 489 /* Error allocating dbcount */ 490 { PR_1_ALLOCATE_DBCOUNT, 491 N_("@A @d @b array: %m\n"), 492 PROMPT_NONE, PR_FATAL }, 493 494 /* Error while scanning inodes */ 495 { PR_1_ISCAN_ERROR, 496 N_("Error while scanning @is (%i): %m\n"), 497 PROMPT_NONE, PR_FATAL }, 498 499 /* Error while iterating over blocks */ 500 { PR_1_BLOCK_ITERATE, 501 N_("Error while iterating over @bs in @i %i: %m\n"), 502 PROMPT_NONE, PR_FATAL }, 503 504 /* Error while storing inode count information */ 505 { PR_1_ICOUNT_STORE, 506 N_("Error storing @i count information (@i=%i, count=%N): %m\n"), 507 PROMPT_NONE, PR_FATAL }, 508 509 /* Error while storing directory block information */ 510 { PR_1_ADD_DBLOCK, 511 N_("Error storing @d @b information " 512 "(@i=%i, @b=%b, num=%N): %m\n"), 513 PROMPT_NONE, PR_FATAL }, 514 515 /* Error while reading inode (for clearing) */ 516 { PR_1_READ_INODE, 517 N_("Error reading @i %i: %m\n"), 518 PROMPT_NONE, PR_FATAL }, 519 520 /* Suppress messages prompt */ 521 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK }, 522 523 /* Filesystem contains large files, but has no such flag in sb */ 524 { PR_1_FEATURE_LARGE_FILES, 525 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"), 526 PROMPT_FIX, 0 }, 527 528 /* Imagic flag set on an inode when filesystem doesn't support it */ 529 { PR_1_SET_IMAGIC, 530 N_("@i %i has imagic flag set. "), 531 PROMPT_CLEAR, 0 }, 532 533 /* Immutable flag set on a device or socket inode */ 534 { PR_1_SET_IMMUTABLE, 535 N_("Special (@v/socket/fifo) @i %i has immutable or " 536 "append-only flag set.\n"), 537 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK }, 538 539 /* Compression flag set on an inode when filesystem doesn't support it */ 540 { PR_1_COMPR_SET, 541 N_("@i %i has @cion flag set on @f without @cion support. "), 542 PROMPT_CLEAR, 0 }, 543 544 /* Non-zero size for device, fifo or socket inode */ 545 { PR_1_SET_NONZSIZE, 546 "Special (@v/socket/fifo) @i %i has non-zero size. ", 547 PROMPT_FIX, PR_PREEN_OK }, 548 549 /* Filesystem revision is 0, but feature flags are set */ 550 { PR_1_FS_REV_LEVEL, 551 "@f has feature flag(s) set, but is a revision 0 @f. ", 552 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK }, 553 554 /* Journal inode is not in use, but contains data */ 555 { PR_1_JOURNAL_INODE_NOT_CLEAR, 556 "@j @i is not in use, but contains data. ", 557 PROMPT_CLEAR, PR_PREEN_OK }, 558 559 /* Journal has bad mode */ 560 { PR_1_JOURNAL_BAD_MODE, 561 N_("@j is not regular file. "), 562 PROMPT_FIX, PR_PREEN_OK }, 563 564 /* Deal with inodes that were part of orphan linked list */ 565 { PR_1_LOW_DTIME, 566 N_("@i %i was part of the orphaned @i list. "), 567 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 }, 568 569 /* Deal with inodes that were part of corrupted orphan linked 570 list (latch question) */ 571 { PR_1_ORPHAN_LIST_REFUGEES, 572 N_("@is that were part of a corrupted orphan linked list found. "), 573 PROMPT_FIX, 0 }, 574 575 /* Pass 1b errors */ 576 577 /* Pass 1B: Rescan for duplicate/bad blocks */ 578 { PR_1B_PASS_HEADER, 579 N_("Duplicate @bs found... invoking duplicate @b passes.\n" 580 "Pass 1B: Rescan for duplicate/bad @bs\n"), 581 PROMPT_NONE, 0 }, 582 583 /* Duplicate/bad block(s) header */ 584 { PR_1B_DUP_BLOCK_HEADER, 585 N_("Duplicate/bad @b(s) in @i %i:"), 586 PROMPT_NONE, 0 }, 587 588 /* Duplicate/bad block(s) in inode */ 589 { PR_1B_DUP_BLOCK, 590 " %b", 591 PROMPT_NONE, PR_LATCH_DBLOCK }, 592 593 /* Duplicate/bad block(s) end */ 594 { PR_1B_DUP_BLOCK_END, 595 "\n", 596 PROMPT_NONE, 0 }, 597 598 /* Error while scanning inodes */ 599 { PR_1B_ISCAN_ERROR, 600 N_("Error while scanning inodes (%i): %m\n"), 601 PROMPT_NONE, PR_FATAL }, 602 603 /* Error allocating inode bitmap */ 604 { PR_1B_ALLOCATE_IBITMAP_ERROR, 605 N_("@A @i @B (inode_dup_map): %m\n"), 606 PROMPT_NONE, PR_FATAL }, 607 608 /* Error while iterating over blocks */ 609 { PR_1B_BLOCK_ITERATE, 610 N_("Error while iterating over @bs in @i %i (%s): %m\n"), 611 PROMPT_NONE, 0 }, 612 613 /* Pass 1C: Scan directories for inodes with dup blocks. */ 614 { PR_1C_PASS_HEADER, 615 N_("Pass 1C: Scan directories for @is with dup @bs.\n"), 616 PROMPT_NONE, 0 }, 617 618 619 /* Pass 1D: Reconciling duplicate blocks */ 620 { PR_1D_PASS_HEADER, 621 N_("Pass 1D: Reconciling duplicate @bs\n"), 622 PROMPT_NONE, 0 }, 623 624 /* File has duplicate blocks */ 625 { PR_1D_DUP_FILE, 626 N_("File %Q (@i #%i, mod time %IM) \n" 627 " has %B duplicate @b(s), shared with %N file(s):\n"), 628 PROMPT_NONE, 0 }, 629 630 /* List of files sharing duplicate blocks */ 631 { PR_1D_DUP_FILE_LIST, 632 N_("\t%Q (@i #%i, mod time %IM)\n"), 633 PROMPT_NONE, 0 }, 634 635 /* File sharing blocks with filesystem metadata */ 636 { PR_1D_SHARE_METADATA, 637 N_("\t<@f metadata>\n"), 638 PROMPT_NONE, 0 }, 639 640 /* Report of how many duplicate/bad inodes */ 641 { PR_1D_NUM_DUP_INODES, 642 N_("(There are %N @is containing duplicate/bad @bs.)\n\n"), 643 PROMPT_NONE, 0 }, 644 645 /* Duplicated blocks already reassigned or cloned. */ 646 { PR_1D_DUP_BLOCKS_DEALT, 647 N_("Duplicated @bs already reassigned or cloned.\n\n"), 648 PROMPT_NONE, 0 }, 649 650 /* Clone duplicate/bad blocks? */ 651 { PR_1D_CLONE_QUESTION, 652 "", PROMPT_CLONE, PR_NO_OK }, 653 654 /* Delete file? */ 655 { PR_1D_DELETE_QUESTION, 656 "", PROMPT_DELETE, 0 }, 657 658 /* Couldn't clone file (error) */ 659 { PR_1D_CLONE_ERROR, 660 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 }, 661 662 /* Pass 2 errors */ 663 664 /* Pass 2: Checking directory structure */ 665 { PR_2_PASS_HEADER, 666 N_("Pass 2: Checking @d structure\n"), 667 PROMPT_NONE, 0 }, 668 669 /* Bad inode number for '.' */ 670 { PR_2_BAD_INODE_DOT, 671 N_("Bad @i number for '.' in @d @i %i.\n"), 672 PROMPT_FIX, 0 }, 673 674 /* Directory entry has bad inode number */ 675 { PR_2_BAD_INO, 676 N_("@E has bad @i #: %Di.\n"), 677 PROMPT_CLEAR, 0 }, 678 679 /* Directory entry has deleted or unused inode */ 680 { PR_2_UNUSED_INODE, 681 N_("@E has @D/unused @i %Di. "), 682 PROMPT_CLEAR, PR_PREEN_OK }, 683 684 /* Directry entry is link to '.' */ 685 { PR_2_LINK_DOT, 686 N_("@E @L to '.' "), 687 PROMPT_CLEAR, 0 }, 688 689 /* Directory entry points to inode now located in a bad block */ 690 { PR_2_BB_INODE, 691 N_("@E points to @i (%Di) located in a bad @b.\n"), 692 PROMPT_CLEAR, 0 }, 693 694 /* Directory entry contains a link to a directory */ 695 { PR_2_LINK_DIR, 696 N_("@E @L to @d %P (%Di).\n"), 697 PROMPT_CLEAR, 0 }, 698 699 /* Directory entry contains a link to the root directry */ 700 { PR_2_LINK_ROOT, 701 N_("@E @L to the @r.\n"), 702 PROMPT_CLEAR, 0 }, 703 704 /* Directory entry has illegal characters in its name */ 705 { PR_2_BAD_NAME, 706 N_("@E has illegal characters in its name.\n"), 707 PROMPT_FIX, 0 }, 708 709 /* Missing '.' in directory inode */ 710 { PR_2_MISSING_DOT, 711 N_("Missing '.' in @d @i %i.\n"), 712 PROMPT_FIX, 0 }, 713 714 /* Missing '..' in directory inode */ 715 { PR_2_MISSING_DOT_DOT, 716 N_("Missing '..' in @d @i %i.\n"), 717 PROMPT_FIX, 0 }, 718 719 /* First entry in directory inode doesn't contain '.' */ 720 { PR_2_1ST_NOT_DOT, 721 N_("First @e '%Dn' (inode=%Di) in @d @i %i (%p) @s '.'\n"), 722 PROMPT_FIX, 0 }, 723 724 /* Second entry in directory inode doesn't contain '..' */ 725 { PR_2_2ND_NOT_DOT_DOT, 726 N_("Second @e '%Dn' (inode=%Di) in @d @i %i @s '..'\n"), 727 PROMPT_FIX, 0 }, 728 729 /* i_faddr should be zero */ 730 { PR_2_FADDR_ZERO, 731 N_("i_faddr @F %IF, @s zero.\n"), 732 PROMPT_CLEAR, 0 }, 733 734 /* i_file_acl should be zero */ 735 { PR_2_FILE_ACL_ZERO, 736 N_("i_file_acl @F %If, @s zero.\n"), 737 PROMPT_CLEAR, 0 }, 738 739 /* i_dir_acl should be zero */ 740 { PR_2_DIR_ACL_ZERO, 741 N_("i_dir_acl @F %Id, @s zero.\n"), 742 PROMPT_CLEAR, 0 }, 743 744 /* i_frag should be zero */ 745 { PR_2_FRAG_ZERO, 746 N_("i_frag @F %N, @s zero.\n"), 747 PROMPT_CLEAR, 0 }, 748 749 /* i_fsize should be zero */ 750 { PR_2_FSIZE_ZERO, 751 N_("i_fsize @F %N, @s zero.\n"), 752 PROMPT_CLEAR, 0 }, 753 754 /* inode has bad mode */ 755 { PR_2_BAD_MODE, 756 N_("@i %i (%Q) has a bad mode (%Im).\n"), 757 PROMPT_CLEAR, 0 }, 758 759 /* directory corrupted */ 760 { PR_2_DIR_CORRUPTED, 761 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"), 762 PROMPT_SALVAGE, 0 }, 763 764 /* filename too long */ 765 { PR_2_FILENAME_LONG, 766 N_("@d @i %i, @b %B, offset %N: filename too long\n"), 767 PROMPT_TRUNCATE, 0 }, 768 769 /* Directory inode has a missing block (hole) */ 770 { PR_2_DIRECTORY_HOLE, 771 N_("@d @i %i has an unallocated @b #%B. "), 772 PROMPT_ALLOCATE, 0 }, 773 774 /* '.' is not NULL terminated */ 775 { PR_2_DOT_NULL_TERM, 776 N_("'.' @d @e in @d @i %i is not NULL terminated\n"), 777 PROMPT_FIX, 0 }, 778 779 /* '..' is not NULL terminated */ 780 { PR_2_DOT_DOT_NULL_TERM, 781 N_("'..' @d @e in @d @i %i is not NULL terminated\n"), 782 PROMPT_FIX, 0 }, 783 784 /* Illegal character device inode */ 785 { PR_2_BAD_CHAR_DEV, 786 N_("@i %i (%Q) is an @I character @v.\n"), 787 PROMPT_CLEAR, 0 }, 788 789 /* Illegal block device inode */ 790 { PR_2_BAD_BLOCK_DEV, 791 N_("@i %i (%Q) is an @I @b @v.\n"), 792 PROMPT_CLEAR, 0 }, 793 794 /* Duplicate '.' entry */ 795 { PR_2_DUP_DOT, 796 N_("@E is duplicate '.' @e.\n"), 797 PROMPT_FIX, 0 }, 798 799 /* Duplicate '..' entry */ 800 { PR_2_DUP_DOT_DOT, 801 N_("@E is duplicate '..' @e.\n"), 802 PROMPT_FIX, 0 }, 803 804 /* Internal error: couldn't find dir_info */ 805 { PR_2_NO_DIRINFO, 806 N_("Internal error: couldn't find dir_info for %i.\n"), 807 PROMPT_NONE, PR_FATAL }, 808 809 /* Final rec_len is wrong */ 810 { PR_2_FINAL_RECLEN, 811 N_("@E has rec_len of %dr, should be %N.\n"), 812 PROMPT_FIX, 0 }, 813 814 /* Error allocating icount structure */ 815 { PR_2_ALLOCATE_ICOUNT, 816 N_("@A icount structure: %m\n"), 817 PROMPT_NONE, PR_FATAL }, 818 819 /* Error iterating over directory blocks */ 820 { PR_2_DBLIST_ITERATE, 821 N_("Error interating over @d @bs: %m\n"), 822 PROMPT_NONE, PR_FATAL }, 823 824 /* Error reading directory block */ 825 { PR_2_READ_DIRBLOCK, 826 N_("Error reading @d @b %b (@i %i): %m\n"), 827 PROMPT_CONTINUE, 0 }, 828 829 /* Error writing directory block */ 830 { PR_2_WRITE_DIRBLOCK, 831 N_("Error writing @d @b %b (@i %i): %m\n"), 832 PROMPT_CONTINUE, 0 }, 833 834 /* Error allocating new directory block */ 835 { PR_2_ALLOC_DIRBOCK, 836 N_("@A new @d @b for @i %i (%s): %m\n"), 837 PROMPT_NONE, 0 }, 838 839 /* Error deallocating inode */ 840 { PR_2_DEALLOC_INODE, 841 N_("Error deallocating @i %i: %m\n"), 842 PROMPT_NONE, PR_FATAL }, 843 844 /* Directory entry for '.' is big. Split? */ 845 { PR_2_SPLIT_DOT, 846 N_("@d @e for '.' is big. "), 847 PROMPT_SPLIT, PR_NO_OK }, 848 849 /* Illegal FIFO inode */ 850 { PR_2_BAD_FIFO, 851 N_("@i %i (%Q) is an @I FIFO.\n"), 852 PROMPT_CLEAR, 0 }, 853 854 /* Illegal socket inode */ 855 { PR_2_BAD_SOCKET, 856 N_("@i %i (%Q) is an @I socket.\n"), 857 PROMPT_CLEAR, 0 }, 858 859 /* Directory filetype not set */ 860 { PR_2_SET_FILETYPE, 861 N_("Setting filetype for @E to %N.\n"), 862 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG }, 863 864 /* Directory filetype incorrect */ 865 { PR_2_BAD_FILETYPE, 866 N_("@E has an incorrect filetype (was %dt, should be %N)\n"), 867 PROMPT_FIX, 0 }, 868 869 /* Directory filetype set on filesystem */ 870 { PR_2_CLEAR_FILETYPE, 871 N_("@E has filetype set\n"), 872 PROMPT_CLEAR, PR_PREEN_OK }, 873 874 /* Directory filename is null */ 875 { PR_2_NULL_NAME, 876 N_("@E has a zero-length name\n"), 877 PROMPT_CLEAR, 0 }, 878 879 /* Pass 3 errors */ 880 881 /* Pass 3: Checking directory connectivity */ 882 { PR_3_PASS_HEADER, 883 N_("Pass 3: Checking @d connectivity\n"), 884 PROMPT_NONE, 0 }, 885 886 /* Root inode not allocated */ 887 { PR_3_NO_ROOT_INODE, 888 N_("@r not allocated. "), 889 PROMPT_ALLOCATE, 0 }, 890 891 /* No room in lost+found */ 892 { PR_3_EXPAND_LF_DIR, 893 N_("No room in @l @d. "), 894 PROMPT_EXPAND, 0 }, 895 896 /* Unconnected directory inode */ 897 { PR_3_UNCONNECTED_DIR, 898 N_("Unconnected @d @i %i (%p)\n"), 899 PROMPT_CONNECT, 0 }, 900 901 /* /lost+found not found */ 902 { PR_3_NO_LF_DIR, 903 N_("/@l not found. "), 904 PROMPT_CREATE, PR_PREEN_OK }, 905 906 /* .. entry is incorrect */ 907 { PR_3_BAD_DOT_DOT, 908 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"), 909 PROMPT_FIX, 0 }, 910 911 /* Bad or non-existent /lost+found. Cannot reconnect */ 912 { PR_3_NO_LPF, 913 N_("Bad or non-existent /@l. Cannot reconnect\n"), 914 PROMPT_NONE, 0 }, 915 916 /* Could not expand /lost+found */ 917 { PR_3_CANT_EXPAND_LPF, 918 N_("Could not expand /@l: %m\n"), 919 PROMPT_NONE, 0 }, 920 921 /* Could not reconnect inode */ 922 { PR_3_CANT_RECONNECT, 923 N_("Could not reconnect %i: %m\n"), 924 PROMPT_NONE, 0 }, 925 926 /* Error while trying to find /lost+found */ 927 { PR_3_ERR_FIND_LPF, 928 N_("Error while trying to find /@l: %m\n"), 929 PROMPT_NONE, 0 }, 930 931 /* Error in ext2fs_new_block while creating /lost+found */ 932 { PR_3_ERR_LPF_NEW_BLOCK, 933 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"), 934 PROMPT_NONE, 0 }, 935 936 /* Error in ext2fs_new_inode while creating /lost+found */ 937 { PR_3_ERR_LPF_NEW_INODE, 938 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"), 939 PROMPT_NONE, 0 }, 940 941 /* Error in ext2fs_new_dir_block while creating /lost+found */ 942 { PR_3_ERR_LPF_NEW_DIR_BLOCK, 943 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"), 944 PROMPT_NONE, 0 }, 945 946 /* Error while writing directory block for /lost+found */ 947 { PR_3_ERR_LPF_WRITE_BLOCK, 948 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"), 949 PROMPT_NONE, 0 }, 950 951 /* Error while adjusting inode count */ 952 { PR_3_ADJUST_INODE, 953 N_("Error while adjusting @i count on @i %i\n"), 954 PROMPT_NONE, 0 }, 955 956 /* Couldn't fix parent directory -- error */ 957 { PR_3_FIX_PARENT_ERR, 958 N_("Couldn't fix parent of @i %i: %m\n\n"), 959 PROMPT_NONE, 0 }, 960 961 /* Couldn't fix parent directory -- couldn't find it */ 962 { PR_3_FIX_PARENT_NOFIND, 963 N_("Couldn't fix parent of @i %i: Couldn't find parent @d entry\n\n"), 964 PROMPT_NONE, 0 }, 965 966 /* Error allocating inode bitmap */ 967 { PR_3_ALLOCATE_IBITMAP_ERROR, 968 N_("@A @i @B (%N): %m\n"), 969 PROMPT_NONE, PR_FATAL }, 970 971 /* Error creating root directory */ 972 { PR_3_CREATE_ROOT_ERROR, 973 N_("Error creating root @d (%s): %m\n"), 974 PROMPT_NONE, PR_FATAL }, 975 976 /* Error creating lost and found directory */ 977 { PR_3_CREATE_LPF_ERROR, 978 N_("Error creating /@l @d (%s): %m\n"), 979 PROMPT_NONE, PR_FATAL }, 980 981 /* Root inode is not directory; aborting */ 982 { PR_3_ROOT_NOT_DIR_ABORT, 983 N_("@r is not a @d; aborting.\n"), 984 PROMPT_NONE, PR_FATAL }, 985 986 /* Cannot proceed without a root inode. */ 987 { PR_3_NO_ROOT_INODE_ABORT, 988 N_("Cannot proceed without a @r.\n"), 989 PROMPT_NONE, PR_FATAL }, 990 991 /* Internal error: couldn't find dir_info */ 992 { PR_3_NO_DIRINFO, 993 N_("Internal error: couldn't find dir_info for %i.\n"), 994 PROMPT_NONE, PR_FATAL }, 995 996 /* Lost+found not a directory */ 997 { PR_3_LPF_NOTDIR, 998 N_("/@l is not a @d (ino=%i)\n"), 999 PROMPT_UNLINK, 0 }, 1000 1001 /* Pass 4 errors */ 1002 1003 /* Pass 4: Checking reference counts */ 1004 { PR_4_PASS_HEADER, 1005 N_("Pass 4: Checking reference counts\n"), 1006 PROMPT_NONE, 0 }, 1007 1008 /* Unattached zero-length inode */ 1009 { PR_4_ZERO_LEN_INODE, 1010 "@u @z @i %i. ", 1011 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK }, 1012 1013 /* Unattached inode */ 1014 { PR_4_UNATTACHED_INODE, 1015 "@u @i %i\n", 1016 PROMPT_CONNECT, 0 }, 1017 1018 /* Inode ref count wrong */ 1019 { PR_4_BAD_REF_COUNT, 1020 N_("@i %i ref count is %Il, @s %N. "), 1021 PROMPT_FIX, PR_PREEN_OK }, 1022 1023 { PR_4_INCONSISTENT_COUNT, 1024 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n" 1025 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n" 1026 "@i_link_info[%i] is %N, @i.i_links_count is %Il. " 1027 "They should be the same!\n"), 1028 PROMPT_NONE, 0 }, 1029 1030 /* Pass 5 errors */ 1031 1032 /* Pass 5: Checking group summary information */ 1033 { PR_5_PASS_HEADER, 1034 N_("Pass 5: Checking @g summary information\n"), 1035 PROMPT_NONE, 0 }, 1036 1037 /* Padding at end of inode bitmap is not set. */ 1038 { PR_5_INODE_BMAP_PADDING, 1039 N_("Padding at end of @i @B is not set. "), 1040 PROMPT_FIX, PR_PREEN_OK }, 1041 1042 /* Padding at end of block bitmap is not set. */ 1043 { PR_5_BLOCK_BMAP_PADDING, 1044 N_("Padding at end of @b @B is not set. "), 1045 PROMPT_FIX, PR_PREEN_OK }, 1046 1047 /* Block bitmap differences header */ 1048 { PR_5_BLOCK_BITMAP_HEADER, 1049 N_("@b @B differences: "), 1050 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG}, 1051 1052 /* Block not used, but marked in bitmap */ 1053 { PR_5_UNUSED_BLOCK, 1054 " -%b", 1055 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, 1056 1057 /* Block used, but not marked used in bitmap */ 1058 { PR_5_BLOCK_USED, 1059 " +%b", 1060 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, 1061 1062 /* Block bitmap differences end */ 1063 { PR_5_BLOCK_BITMAP_END, 1064 "\n", 1065 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 1066 1067 /* Inode bitmap differences header */ 1068 { PR_5_INODE_BITMAP_HEADER, 1069 N_("@i @B differences: "), 1070 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG }, 1071 1072 /* Inode not used, but marked in bitmap */ 1073 { PR_5_UNUSED_INODE, 1074 " -%i", 1075 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, 1076 1077 /* Inode used, but not marked used in bitmap */ 1078 { PR_5_INODE_USED, 1079 " +%i", 1080 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, 1081 1082 /* Inode bitmap differences end */ 1083 { PR_5_INODE_BITMAP_END, 1084 "\n", 1085 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 1086 1087 /* Free inodes count for group wrong */ 1088 { PR_5_FREE_INODE_COUNT_GROUP, 1089 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"), 1090 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 1091 1092 /* Directories count for group wrong */ 1093 { PR_5_FREE_DIR_COUNT_GROUP, 1094 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"), 1095 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 1096 1097 /* Free inodes count wrong */ 1098 { PR_5_FREE_INODE_COUNT, 1099 N_("Free @is count wrong (%i, counted=%j).\n"), 1100 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 1101 1102 /* Free blocks count for group wrong */ 1103 { PR_5_FREE_BLOCK_COUNT_GROUP, 1104 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"), 1105 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 1106 1107 /* Free blocks count wrong */ 1108 { PR_5_FREE_BLOCK_COUNT, 1109 N_("Free @bs count wrong (%b, counted=%c).\n"), 1110 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, 1111 1112 /* Programming error: bitmap endpoints don't match */ 1113 { PR_5_BMAP_ENDPOINTS, 1114 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't " 1115 "match calculated @B endpoints (%i, %j)\n"), 1116 PROMPT_NONE, PR_FATAL }, 1117 1118 /* Internal error: fudging end of bitmap */ 1119 { PR_5_FUDGE_BITMAP_ERROR, 1120 N_("Internal error: fudging end of bitmap (%N)\n"), 1121 PROMPT_NONE, PR_FATAL }, 1122 1123 /* Error copying in replacement inode bitmap */ 1124 { PR_5_COPY_IBITMAP_ERROR, 1125 "Error copying in replacement @i @B: %m\n", 1126 PROMPT_NONE, PR_FATAL }, 1127 1128 /* Error copying in replacement block bitmap */ 1129 { PR_5_COPY_BBITMAP_ERROR, 1130 "Error copying in replacement @b @B: %m\n", 1131 PROMPT_NONE, PR_FATAL }, 1132 1133 { 0 } 1134}; 1135 1136/* 1137 * This is the latch flags register. It allows several problems to be 1138 * "latched" together. This means that the user has to answer but one 1139 * question for the set of problems, and all of the associated 1140 * problems will be either fixed or not fixed. 1141 */ 1142static struct latch_descr pr_latch_info[] = { 1143 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 }, 1144 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 }, 1145 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END }, 1146 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END }, 1147 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 }, 1148 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END }, 1149 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 }, 1150 { -1, 0, 0 }, 1151}; 1152 1153static const struct e2fsck_problem *find_problem(int code) 1154{ 1155 int i; 1156 1157 for (i=0; problem_table[i].e2p_code; i++) { 1158 if (problem_table[i].e2p_code == code) 1159 return &problem_table[i]; 1160 } 1161 return 0; 1162} 1163 1164static struct latch_descr *find_latch(int code) 1165{ 1166 int i; 1167 1168 for (i=0; pr_latch_info[i].latch_code >= 0; i++) { 1169 if (pr_latch_info[i].latch_code == code) 1170 return &pr_latch_info[i]; 1171 } 1172 return 0; 1173} 1174 1175int end_problem_latch(e2fsck_t ctx, int mask) 1176{ 1177 struct latch_descr *ldesc; 1178 struct problem_context pctx; 1179 int answer = -1; 1180 1181 ldesc = find_latch(mask); 1182 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) { 1183 clear_problem_context(&pctx); 1184 answer = fix_problem(ctx, ldesc->end_message, &pctx); 1185 } 1186 ldesc->flags &= ~(PRL_VARIABLE); 1187 return answer; 1188} 1189 1190int set_latch_flags(int mask, int setflags, int clearflags) 1191{ 1192 struct latch_descr *ldesc; 1193 1194 ldesc = find_latch(mask); 1195 if (!ldesc) 1196 return -1; 1197 ldesc->flags |= setflags; 1198 ldesc->flags &= ~clearflags; 1199 return 0; 1200} 1201 1202int get_latch_flags(int mask, int *value) 1203{ 1204 struct latch_descr *ldesc; 1205 1206 ldesc = find_latch(mask); 1207 if (!ldesc) 1208 return -1; 1209 *value = ldesc->flags; 1210 return 0; 1211} 1212 1213void clear_problem_context(struct problem_context *ctx) 1214{ 1215 memset(ctx, 0, sizeof(struct problem_context)); 1216 ctx->blkcount = -1; 1217 ctx->group = -1; 1218} 1219 1220int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) 1221{ 1222 ext2_filsys fs = ctx->fs; 1223 const struct e2fsck_problem *ptr; 1224 struct latch_descr *ldesc = 0; 1225 const char *message; 1226 int def_yn, answer, ans; 1227 int print_answer = 0; 1228 int suppress = 0; 1229 1230 ptr = find_problem(code); 1231 if (!ptr) { 1232 printf(_("Unhandled error code (%d)!\n"), code); 1233 return 0; 1234 } 1235 def_yn = 1; 1236 if ((ptr->flags & PR_NO_DEFAULT) || 1237 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) || 1238 (ctx->options & E2F_OPT_NO)) 1239 def_yn= 0; 1240 1241 /* 1242 * Do special latch processing. This is where we ask the 1243 * latch question, if it exists 1244 */ 1245 if (ptr->flags & PR_LATCH_MASK) { 1246 ldesc = find_latch(ptr->flags & PR_LATCH_MASK); 1247 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) { 1248 ans = fix_problem(ctx, ldesc->question, pctx); 1249 if (ans == 1) 1250 ldesc->flags |= PRL_YES; 1251 if (ans == 0) 1252 ldesc->flags |= PRL_NO; 1253 ldesc->flags |= PRL_LATCHED; 1254 } 1255 if (ldesc->flags & PRL_SUPPRESS) 1256 suppress++; 1257 } 1258 if ((ptr->flags & PR_PREEN_NOMSG) && 1259 (ctx->options & E2F_OPT_PREEN)) 1260 suppress++; 1261 if ((ptr->flags & PR_NO_NOMSG) && 1262 (ctx->options & E2F_OPT_NO)) 1263 suppress++; 1264 if (!suppress) { 1265 message = ptr->e2p_description; 1266 if (ctx->options & E2F_OPT_PREEN) { 1267 printf("%s: ", ctx->device_name); 1268#if 0 1269 if (ptr->e2p_preen_msg) 1270 message = ptr->e2p_preen_msg; 1271#endif 1272 } 1273 print_e2fsck_message(ctx, _(message), pctx, 1); 1274 } 1275 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE)) 1276 preenhalt(ctx); 1277 1278 if (ptr->flags & PR_FATAL) 1279 fatal_error(ctx, 0); 1280 1281 if (ptr->prompt == PROMPT_NONE) { 1282 if (ptr->flags & PR_NOCOLLATE) 1283 answer = -1; 1284 else 1285 answer = def_yn; 1286 } else { 1287 if (ctx->options & E2F_OPT_PREEN) { 1288 answer = def_yn; 1289 if (!(ptr->flags & PR_PREEN_NOMSG)) 1290 print_answer = 1; 1291 } else if ((ptr->flags & PR_LATCH_MASK) && 1292 (ldesc->flags & (PRL_YES | PRL_NO))) { 1293 if (!suppress) 1294 print_answer = 1; 1295 if (ldesc->flags & PRL_YES) 1296 answer = 1; 1297 else 1298 answer = 0; 1299 } else 1300 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn); 1301 if (!answer && !(ptr->flags & PR_NO_OK)) 1302 ext2fs_unmark_valid(fs); 1303 1304 if (print_answer) 1305 printf("%s.\n", answer ? 1306 _(preen_msg[(int) ptr->prompt]) : _("IGNORED")); 1307 1308 } 1309 1310 if ((ptr->prompt == PROMPT_ABORT) && answer) 1311 fatal_error(ctx, 0); 1312 1313 if (ptr->flags & PR_AFTER_CODE) 1314 answer = fix_problem(ctx, ptr->second_code, pctx); 1315 1316 return answer; 1317} 1318