1 /* 2 * pass2.c --- check directory structure 3 * 4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 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 * Pass 2 of e2fsck iterates through all active directory inodes, and 12 * applies to following tests to each directory entry in the directory 13 * blocks in the inodes: 14 * 15 * - The length of the directory entry (rec_len) should be at 16 * least 8 bytes, and no more than the remaining space 17 * left in the directory block. 18 * - The length of the name in the directory entry (name_len) 19 * should be less than (rec_len - 8). 20 * - The inode number in the directory entry should be within 21 * legal bounds. 22 * - The inode number should refer to a in-use inode. 23 * - The first entry should be '.', and its inode should be 24 * the inode of the directory. 25 * - The second entry should be '..'. 26 * 27 * To minimize disk seek time, the directory blocks are processed in 28 * sorted order of block numbers. 29 * 30 * Pass 2 also collects the following information: 31 * - The inode numbers of the subdirectories for each directory. 32 * 33 * Pass 2 relies on the following information from previous passes: 34 * - The directory information collected in pass 1. 35 * - The inode_used_map bitmap 36 * - The inode_bad_map bitmap 37 * - The inode_dir_map bitmap 38 * 39 * Pass 2 frees the following data structures 40 * - The inode_bad_map bitmap 41 * - The inode_reg_map bitmap 42 */ 43 44 #define _GNU_SOURCE 1 /* get strnlen() */ 45 #include <string.h> 46 47 #include "e2fsck.h" 48 #include "problem.h" 49 #include "dict.h" 50 51 #ifdef NO_INLINE_FUNCS 52 #define _INLINE_ 53 #else 54 #define _INLINE_ inline 55 #endif 56 57 /* #define DX_DEBUG */ 58 59 /* 60 * Keeps track of how many times an inode is referenced. 61 */ 62 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf); 63 static int check_dir_block(ext2_filsys fs, 64 struct ext2_db_entry *dir_blocks_info, 65 void *priv_data); 66 static int allocate_dir_block(e2fsck_t ctx, 67 struct ext2_db_entry *dir_blocks_info, 68 char *buf, struct problem_context *pctx); 69 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino); 70 static int htree_depth(struct dx_dir_info *dx_dir, 71 struct dx_dirblock_info *dx_db); 72 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b); 73 74 struct check_dir_struct { 75 char *buf; 76 struct problem_context pctx; 77 int count, max; 78 e2fsck_t ctx; 79 }; 80 81 void e2fsck_pass2(e2fsck_t ctx) 82 { 83 struct ext2_super_block *sb = ctx->fs->super; 84 struct problem_context pctx; 85 ext2_filsys fs = ctx->fs; 86 char *buf; 87 #ifdef RESOURCE_TRACK 88 struct resource_track rtrack; 89 #endif 90 struct check_dir_struct cd; 91 struct dx_dir_info *dx_dir; 92 struct dx_dirblock_info *dx_db, *dx_parent; 93 int b; 94 int i, depth; 95 problem_t code; 96 int bad_dir; 97 98 init_resource_track(&rtrack, ctx->fs->io); 99 clear_problem_context(&cd.pctx); 100 101 #ifdef MTRACE 102 mtrace_print("Pass 2"); 103 #endif 104 105 if (!(ctx->options & E2F_OPT_PREEN)) 106 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx); 107 108 e2fsck_setup_tdb_icount(ctx, EXT2_ICOUNT_OPT_INCREMENT, 109 &ctx->inode_count); 110 if (ctx->inode_count) 111 cd.pctx.errcode = 0; 112 else 113 cd.pctx.errcode = ext2fs_create_icount2(fs, 114 EXT2_ICOUNT_OPT_INCREMENT, 115 0, ctx->inode_link_info, 116 &ctx->inode_count); 117 if (cd.pctx.errcode) { 118 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx); 119 ctx->flags |= E2F_FLAG_ABORT; 120 return; 121 } 122 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize, 123 "directory scan buffer"); 124 125 /* 126 * Set up the parent pointer for the root directory, if 127 * present. (If the root directory is not present, we will 128 * create it in pass 3.) 129 */ 130 (void) e2fsck_dir_info_set_parent(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO); 131 132 cd.buf = buf; 133 cd.ctx = ctx; 134 cd.count = 1; 135 cd.max = ext2fs_dblist_count(fs->dblist); 136 137 if (ctx->progress) 138 (void) (ctx->progress)(ctx, 2, 0, cd.max); 139 140 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) 141 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp); 142 143 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block, 144 &cd); 145 if (ctx->flags & E2F_FLAG_SIGNAL_MASK || ctx->flags & E2F_FLAG_RESTART) 146 return; 147 148 if (ctx->flags & E2F_FLAG_RESTART_LATER) { 149 ctx->flags |= E2F_FLAG_RESTART; 150 return; 151 } 152 153 if (cd.pctx.errcode) { 154 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx); 155 ctx->flags |= E2F_FLAG_ABORT; 156 return; 157 } 158 159 #ifdef ENABLE_HTREE 160 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) { 161 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 162 return; 163 if (dx_dir->numblocks == 0) 164 continue; 165 clear_problem_context(&pctx); 166 bad_dir = 0; 167 pctx.dir = dx_dir->ino; 168 dx_db = dx_dir->dx_block; 169 if (dx_db->flags & DX_FLAG_REFERENCED) 170 dx_db->flags |= DX_FLAG_DUP_REF; 171 else 172 dx_db->flags |= DX_FLAG_REFERENCED; 173 /* 174 * Find all of the first and last leaf blocks, and 175 * update their parent's min and max hash values 176 */ 177 for (b=0, dx_db = dx_dir->dx_block; 178 b < dx_dir->numblocks; 179 b++, dx_db++) { 180 if ((dx_db->type != DX_DIRBLOCK_LEAF) || 181 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST))) 182 continue; 183 dx_parent = &dx_dir->dx_block[dx_db->parent]; 184 /* 185 * XXX Make sure dx_parent->min_hash > dx_db->min_hash 186 */ 187 if (dx_db->flags & DX_FLAG_FIRST) 188 dx_parent->min_hash = dx_db->min_hash; 189 /* 190 * XXX Make sure dx_parent->max_hash < dx_db->max_hash 191 */ 192 if (dx_db->flags & DX_FLAG_LAST) 193 dx_parent->max_hash = dx_db->max_hash; 194 } 195 196 for (b=0, dx_db = dx_dir->dx_block; 197 b < dx_dir->numblocks; 198 b++, dx_db++) { 199 pctx.blkcount = b; 200 pctx.group = dx_db->parent; 201 code = 0; 202 if (!(dx_db->flags & DX_FLAG_FIRST) && 203 (dx_db->min_hash < dx_db->node_min_hash)) { 204 pctx.blk = dx_db->min_hash; 205 pctx.blk2 = dx_db->node_min_hash; 206 code = PR_2_HTREE_MIN_HASH; 207 fix_problem(ctx, code, &pctx); 208 bad_dir++; 209 } 210 if (dx_db->type == DX_DIRBLOCK_LEAF) { 211 depth = htree_depth(dx_dir, dx_db); 212 if (depth != dx_dir->depth) { 213 pctx.num = dx_dir->depth; 214 code = PR_2_HTREE_BAD_DEPTH; 215 fix_problem(ctx, code, &pctx); 216 bad_dir++; 217 } 218 } 219 /* 220 * This test doesn't apply for the root block 221 * at block #0 222 */ 223 if (b && 224 (dx_db->max_hash > dx_db->node_max_hash)) { 225 pctx.blk = dx_db->max_hash; 226 pctx.blk2 = dx_db->node_max_hash; 227 code = PR_2_HTREE_MAX_HASH; 228 fix_problem(ctx, code, &pctx); 229 bad_dir++; 230 } 231 if (!(dx_db->flags & DX_FLAG_REFERENCED)) { 232 code = PR_2_HTREE_NOTREF; 233 fix_problem(ctx, code, &pctx); 234 bad_dir++; 235 } else if (dx_db->flags & DX_FLAG_DUP_REF) { 236 code = PR_2_HTREE_DUPREF; 237 fix_problem(ctx, code, &pctx); 238 bad_dir++; 239 } 240 } 241 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) { 242 clear_htree(ctx, dx_dir->ino); 243 dx_dir->numblocks = 0; 244 } 245 } 246 e2fsck_free_dx_dir_info(ctx); 247 #endif 248 ext2fs_free_mem(&buf); 249 ext2fs_free_dblist(fs->dblist); 250 251 if (ctx->inode_bad_map) { 252 ext2fs_free_inode_bitmap(ctx->inode_bad_map); 253 ctx->inode_bad_map = 0; 254 } 255 if (ctx->inode_reg_map) { 256 ext2fs_free_inode_bitmap(ctx->inode_reg_map); 257 ctx->inode_reg_map = 0; 258 } 259 260 clear_problem_context(&pctx); 261 if (ctx->large_files) { 262 if (!(sb->s_feature_ro_compat & 263 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) && 264 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) { 265 sb->s_feature_ro_compat |= 266 EXT2_FEATURE_RO_COMPAT_LARGE_FILE; 267 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 268 ext2fs_mark_super_dirty(fs); 269 } 270 if (sb->s_rev_level == EXT2_GOOD_OLD_REV && 271 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) { 272 ext2fs_update_dynamic_rev(fs); 273 ext2fs_mark_super_dirty(fs); 274 } 275 } 276 277 print_resource_track(ctx, _("Pass 2"), &rtrack, fs->io); 278 } 279 280 #define MAX_DEPTH 32000 281 static int htree_depth(struct dx_dir_info *dx_dir, 282 struct dx_dirblock_info *dx_db) 283 { 284 int depth = 0; 285 286 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) { 287 dx_db = &dx_dir->dx_block[dx_db->parent]; 288 depth++; 289 } 290 return depth; 291 } 292 293 static int dict_de_cmp(const void *a, const void *b) 294 { 295 const struct ext2_dir_entry *de_a, *de_b; 296 int a_len, b_len; 297 298 de_a = (const struct ext2_dir_entry *) a; 299 a_len = de_a->name_len & 0xFF; 300 de_b = (const struct ext2_dir_entry *) b; 301 b_len = de_b->name_len & 0xFF; 302 303 if (a_len != b_len) 304 return (a_len - b_len); 305 306 return strncmp(de_a->name, de_b->name, a_len); 307 } 308 309 /* 310 * This is special sort function that makes sure that directory blocks 311 * with a dirblock of zero are sorted to the beginning of the list. 312 * This guarantees that the root node of the htree directories are 313 * processed first, so we know what hash version to use. 314 */ 315 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b) 316 { 317 const struct ext2_db_entry *db_a = 318 (const struct ext2_db_entry *) a; 319 const struct ext2_db_entry *db_b = 320 (const struct ext2_db_entry *) b; 321 322 if (db_a->blockcnt && !db_b->blockcnt) 323 return 1; 324 325 if (!db_a->blockcnt && db_b->blockcnt) 326 return -1; 327 328 if (db_a->blk != db_b->blk) 329 return (int) (db_a->blk - db_b->blk); 330 331 if (db_a->ino != db_b->ino) 332 return (int) (db_a->ino - db_b->ino); 333 334 return (int) (db_a->blockcnt - db_b->blockcnt); 335 } 336 337 338 /* 339 * Make sure the first entry in the directory is '.', and that the 340 * directory entry is sane. 341 */ 342 static int check_dot(e2fsck_t ctx, 343 struct ext2_dir_entry *dirent, 344 ext2_ino_t ino, struct problem_context *pctx) 345 { 346 struct ext2_dir_entry *nextdir; 347 unsigned int rec_len, new_len; 348 int status = 0; 349 int created = 0; 350 int problem = 0; 351 352 if (!dirent->inode) 353 problem = PR_2_MISSING_DOT; 354 else if (((dirent->name_len & 0xFF) != 1) || 355 (dirent->name[0] != '.')) 356 problem = PR_2_1ST_NOT_DOT; 357 else if (dirent->name[1] != '\0') 358 problem = PR_2_DOT_NULL_TERM; 359 360 (void) ext2fs_get_rec_len(ctx->fs, dirent, &rec_len); 361 if (problem) { 362 if (fix_problem(ctx, problem, pctx)) { 363 if (rec_len < 12) 364 rec_len = dirent->rec_len = 12; 365 dirent->inode = ino; 366 dirent->name_len = 1; 367 dirent->name[0] = '.'; 368 dirent->name[1] = '\0'; 369 status = 1; 370 created = 1; 371 } 372 } 373 if (dirent->inode != ino) { 374 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) { 375 dirent->inode = ino; 376 status = 1; 377 } 378 } 379 if (rec_len > 12) { 380 new_len = rec_len - 12; 381 if (new_len > 12) { 382 if (created || 383 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) { 384 nextdir = (struct ext2_dir_entry *) 385 ((char *) dirent + 12); 386 dirent->rec_len = 12; 387 (void) ext2fs_set_rec_len(ctx->fs, new_len, 388 nextdir); 389 nextdir->inode = 0; 390 nextdir->name_len = 0; 391 status = 1; 392 } 393 } 394 } 395 return status; 396 } 397 398 /* 399 * Make sure the second entry in the directory is '..', and that the 400 * directory entry is sane. We do not check the inode number of '..' 401 * here; this gets done in pass 3. 402 */ 403 static int check_dotdot(e2fsck_t ctx, 404 struct ext2_dir_entry *dirent, 405 ext2_ino_t ino, struct problem_context *pctx) 406 { 407 int rec_len, problem = 0; 408 409 if (!dirent->inode) 410 problem = PR_2_MISSING_DOT_DOT; 411 else if (((dirent->name_len & 0xFF) != 2) || 412 (dirent->name[0] != '.') || 413 (dirent->name[1] != '.')) 414 problem = PR_2_2ND_NOT_DOT_DOT; 415 else if (dirent->name[2] != '\0') 416 problem = PR_2_DOT_DOT_NULL_TERM; 417 418 (void) ext2fs_get_rec_len(ctx->fs, dirent, &rec_len); 419 if (problem) { 420 if (fix_problem(ctx, problem, pctx)) { 421 if (rec_len < 12) 422 dirent->rec_len = 12; 423 /* 424 * Note: we don't have the parent inode just 425 * yet, so we will fill it in with the root 426 * inode. This will get fixed in pass 3. 427 */ 428 dirent->inode = EXT2_ROOT_INO; 429 dirent->name_len = 2; 430 dirent->name[0] = '.'; 431 dirent->name[1] = '.'; 432 dirent->name[2] = '\0'; 433 return 1; 434 } 435 return 0; 436 } 437 if (e2fsck_dir_info_set_dotdot(ctx, ino, dirent->inode)) { 438 fix_problem(ctx, PR_2_NO_DIRINFO, pctx); 439 return -1; 440 } 441 return 0; 442 } 443 444 /* 445 * Check to make sure a directory entry doesn't contain any illegal 446 * characters. 447 */ 448 static int check_name(e2fsck_t ctx, 449 struct ext2_dir_entry *dirent, 450 ext2_ino_t dir_ino EXT2FS_ATTR((unused)), 451 struct problem_context *pctx) 452 { 453 int i; 454 int fixup = -1; 455 int ret = 0; 456 457 for ( i = 0; i < (dirent->name_len & 0xFF); i++) { 458 if (dirent->name[i] == '/' || dirent->name[i] == '\0') { 459 if (fixup < 0) { 460 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx); 461 } 462 if (fixup) { 463 dirent->name[i] = '.'; 464 ret = 1; 465 } 466 } 467 } 468 return ret; 469 } 470 471 /* 472 * Check the directory filetype (if present) 473 */ 474 static _INLINE_ int check_filetype(e2fsck_t ctx, 475 struct ext2_dir_entry *dirent, 476 ext2_ino_t dir_ino EXT2FS_ATTR((unused)), 477 struct problem_context *pctx) 478 { 479 int filetype = dirent->name_len >> 8; 480 int should_be = EXT2_FT_UNKNOWN; 481 struct ext2_inode inode; 482 483 if (!(ctx->fs->super->s_feature_incompat & 484 EXT2_FEATURE_INCOMPAT_FILETYPE)) { 485 if (filetype == 0 || 486 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx)) 487 return 0; 488 dirent->name_len = dirent->name_len & 0xFF; 489 return 1; 490 } 491 492 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) { 493 should_be = EXT2_FT_DIR; 494 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map, 495 dirent->inode)) { 496 should_be = EXT2_FT_REG_FILE; 497 } else if (ctx->inode_bad_map && 498 ext2fs_test_inode_bitmap(ctx->inode_bad_map, 499 dirent->inode)) 500 should_be = 0; 501 else { 502 e2fsck_read_inode(ctx, dirent->inode, &inode, 503 "check_filetype"); 504 should_be = ext2_file_type(inode.i_mode); 505 } 506 if (filetype == should_be) 507 return 0; 508 pctx->num = should_be; 509 510 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE, 511 pctx) == 0) 512 return 0; 513 514 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8; 515 return 1; 516 } 517 518 #ifdef ENABLE_HTREE 519 static void parse_int_node(ext2_filsys fs, 520 struct ext2_db_entry *db, 521 struct check_dir_struct *cd, 522 struct dx_dir_info *dx_dir, 523 char *block_buf) 524 { 525 struct ext2_dx_root_info *root; 526 struct ext2_dx_entry *ent; 527 struct ext2_dx_countlimit *limit; 528 struct dx_dirblock_info *dx_db; 529 int i, expect_limit, count; 530 blk_t blk; 531 ext2_dirhash_t min_hash = 0xffffffff; 532 ext2_dirhash_t max_hash = 0; 533 ext2_dirhash_t hash = 0, prev_hash; 534 535 if (db->blockcnt == 0) { 536 root = (struct ext2_dx_root_info *) (block_buf + 24); 537 538 #ifdef DX_DEBUG 539 printf("Root node dump:\n"); 540 printf("\t Reserved zero: %u\n", root->reserved_zero); 541 printf("\t Hash Version: %d\n", root->hash_version); 542 printf("\t Info length: %d\n", root->info_length); 543 printf("\t Indirect levels: %d\n", root->indirect_levels); 544 printf("\t Flags: %d\n", root->unused_flags); 545 #endif 546 547 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length); 548 } else { 549 ent = (struct ext2_dx_entry *) (block_buf+8); 550 } 551 limit = (struct ext2_dx_countlimit *) ent; 552 553 #ifdef DX_DEBUG 554 printf("Number of entries (count): %d\n", 555 ext2fs_le16_to_cpu(limit->count)); 556 printf("Number of entries (limit): %d\n", 557 ext2fs_le16_to_cpu(limit->limit)); 558 #endif 559 560 count = ext2fs_le16_to_cpu(limit->count); 561 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) / 562 sizeof(struct ext2_dx_entry); 563 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) { 564 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit); 565 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx)) 566 goto clear_and_exit; 567 } 568 if (count > expect_limit) { 569 cd->pctx.num = count; 570 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx)) 571 goto clear_and_exit; 572 count = expect_limit; 573 } 574 575 for (i=0; i < count; i++) { 576 prev_hash = hash; 577 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0; 578 #ifdef DX_DEBUG 579 printf("Entry #%d: Hash 0x%08x, block %u\n", i, 580 hash, ext2fs_le32_to_cpu(ent[i].block)); 581 #endif 582 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff; 583 /* Check to make sure the block is valid */ 584 if (blk >= (blk_t) dx_dir->numblocks) { 585 cd->pctx.blk = blk; 586 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK, 587 &cd->pctx)) 588 goto clear_and_exit; 589 continue; 590 } 591 if (hash < prev_hash && 592 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx)) 593 goto clear_and_exit; 594 dx_db = &dx_dir->dx_block[blk]; 595 if (dx_db->flags & DX_FLAG_REFERENCED) { 596 dx_db->flags |= DX_FLAG_DUP_REF; 597 } else { 598 dx_db->flags |= DX_FLAG_REFERENCED; 599 dx_db->parent = db->blockcnt; 600 } 601 if (hash < min_hash) 602 min_hash = hash; 603 if (hash > max_hash) 604 max_hash = hash; 605 dx_db->node_min_hash = hash; 606 if ((i+1) < count) 607 dx_db->node_max_hash = 608 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1; 609 else { 610 dx_db->node_max_hash = 0xfffffffe; 611 dx_db->flags |= DX_FLAG_LAST; 612 } 613 if (i == 0) 614 dx_db->flags |= DX_FLAG_FIRST; 615 } 616 #ifdef DX_DEBUG 617 printf("Blockcnt = %d, min hash 0x%08x, max hash 0x%08x\n", 618 db->blockcnt, min_hash, max_hash); 619 #endif 620 dx_db = &dx_dir->dx_block[db->blockcnt]; 621 dx_db->min_hash = min_hash; 622 dx_db->max_hash = max_hash; 623 return; 624 625 clear_and_exit: 626 clear_htree(cd->ctx, cd->pctx.ino); 627 dx_dir->numblocks = 0; 628 } 629 #endif /* ENABLE_HTREE */ 630 631 /* 632 * Given a busted directory, try to salvage it somehow. 633 * 634 */ 635 static void salvage_directory(ext2_filsys fs, 636 struct ext2_dir_entry *dirent, 637 struct ext2_dir_entry *prev, 638 unsigned int *offset) 639 { 640 char *cp = (char *) dirent; 641 int left; 642 unsigned int rec_len, prev_rec_len; 643 unsigned int name_len = dirent->name_len & 0xFF; 644 645 (void) ext2fs_get_rec_len(fs, dirent, &rec_len); 646 left = fs->blocksize - *offset - rec_len; 647 648 /* 649 * Special case of directory entry of size 8: copy what's left 650 * of the directory block up to cover up the invalid hole. 651 */ 652 if ((left >= 12) && (rec_len == 8)) { 653 memmove(cp, cp+8, left); 654 memset(cp + left, 0, 8); 655 return; 656 } 657 /* 658 * If the directory entry overruns the end of the directory 659 * block, and the name is small enough to fit, then adjust the 660 * record length. 661 */ 662 if ((left < 0) && 663 ((int) rec_len + left > 8) && 664 (name_len + 8 <= (int) rec_len + left) && 665 dirent->inode <= fs->super->s_inodes_count && 666 strnlen(dirent->name, name_len) == name_len) { 667 (void) ext2fs_set_rec_len(fs, (int) rec_len + left, dirent); 668 return; 669 } 670 /* 671 * If the record length of the directory entry is a multiple 672 * of four, and not too big, such that it is valid, let the 673 * previous directory entry absorb the invalid one. 674 */ 675 if (prev && rec_len && (rec_len % 4) == 0 && 676 (*offset + rec_len <= fs->blocksize)) { 677 (void) ext2fs_get_rec_len(fs, prev, &prev_rec_len); 678 prev_rec_len += rec_len; 679 (void) ext2fs_set_rec_len(fs, prev_rec_len, prev); 680 *offset += rec_len; 681 return; 682 } 683 /* 684 * Default salvage method --- kill all of the directory 685 * entries for the rest of the block. We will either try to 686 * absorb it into the previous directory entry, or create a 687 * new empty directory entry the rest of the directory block. 688 */ 689 if (prev) { 690 (void) ext2fs_get_rec_len(fs, prev, &prev_rec_len); 691 prev_rec_len += fs->blocksize - *offset; 692 (void) ext2fs_set_rec_len(fs, prev_rec_len, prev); 693 *offset = fs->blocksize; 694 } else { 695 rec_len = fs->blocksize - *offset; 696 (void) ext2fs_set_rec_len(fs, rec_len, dirent); 697 dirent->name_len = 0; 698 dirent->inode = 0; 699 } 700 } 701 702 static int check_dir_block(ext2_filsys fs, 703 struct ext2_db_entry *db, 704 void *priv_data) 705 { 706 struct dx_dir_info *dx_dir; 707 #ifdef ENABLE_HTREE 708 struct dx_dirblock_info *dx_db = 0; 709 #endif /* ENABLE_HTREE */ 710 struct ext2_dir_entry *dirent, *prev; 711 ext2_dirhash_t hash; 712 unsigned int offset = 0; 713 const char * old_op; 714 int dir_modified = 0; 715 int dot_state; 716 unsigned int rec_len; 717 blk_t block_nr = db->blk; 718 ext2_ino_t ino = db->ino; 719 ext2_ino_t subdir_parent; 720 __u16 links; 721 struct check_dir_struct *cd; 722 char *buf; 723 e2fsck_t ctx; 724 int problem; 725 struct ext2_dx_root_info *root; 726 struct ext2_dx_countlimit *limit; 727 static dict_t de_dict; 728 struct problem_context pctx; 729 int dups_found = 0; 730 int ret; 731 732 cd = (struct check_dir_struct *) priv_data; 733 buf = cd->buf; 734 ctx = cd->ctx; 735 736 if (ctx->flags & E2F_FLAG_SIGNAL_MASK || ctx->flags & E2F_FLAG_RESTART) 737 return DIRENT_ABORT; 738 739 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max)) 740 return DIRENT_ABORT; 741 742 /* 743 * Make sure the inode is still in use (could have been 744 * deleted in the duplicate/bad blocks pass. 745 */ 746 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))) 747 return 0; 748 749 cd->pctx.ino = ino; 750 cd->pctx.blk = block_nr; 751 cd->pctx.blkcount = db->blockcnt; 752 cd->pctx.ino2 = 0; 753 cd->pctx.dirent = 0; 754 cd->pctx.num = 0; 755 756 if (db->blk == 0) { 757 if (allocate_dir_block(ctx, db, buf, &cd->pctx)) 758 return 0; 759 block_nr = db->blk; 760 } 761 762 if (db->blockcnt) 763 dot_state = 2; 764 else 765 dot_state = 0; 766 767 if (ctx->dirs_to_hash && 768 ext2fs_u32_list_test(ctx->dirs_to_hash, ino)) 769 dups_found++; 770 771 #if 0 772 printf("In process_dir_block block %lu, #%d, inode %lu\n", block_nr, 773 db->blockcnt, ino); 774 #endif 775 776 old_op = ehandler_operation(_("reading directory block")); 777 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf); 778 ehandler_operation(0); 779 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED) 780 cd->pctx.errcode = 0; /* We'll handle this ourselves */ 781 if (cd->pctx.errcode) { 782 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) { 783 ctx->flags |= E2F_FLAG_ABORT; 784 return DIRENT_ABORT; 785 } 786 memset(buf, 0, fs->blocksize); 787 } 788 #ifdef ENABLE_HTREE 789 dx_dir = e2fsck_get_dx_dir_info(ctx, ino); 790 if (dx_dir && dx_dir->numblocks) { 791 if (db->blockcnt >= dx_dir->numblocks) { 792 if (fix_problem(ctx, PR_2_UNEXPECTED_HTREE_BLOCK, 793 &pctx)) { 794 clear_htree(ctx, ino); 795 dx_dir->numblocks = 0; 796 dx_db = 0; 797 goto out_htree; 798 } 799 fatal_error(ctx, _("Can not continue.")); 800 } 801 dx_db = &dx_dir->dx_block[db->blockcnt]; 802 dx_db->type = DX_DIRBLOCK_LEAF; 803 dx_db->phys = block_nr; 804 dx_db->min_hash = ~0; 805 dx_db->max_hash = 0; 806 807 dirent = (struct ext2_dir_entry *) buf; 808 (void) ext2fs_get_rec_len(fs, dirent, &rec_len); 809 limit = (struct ext2_dx_countlimit *) (buf+8); 810 if (db->blockcnt == 0) { 811 root = (struct ext2_dx_root_info *) (buf + 24); 812 dx_db->type = DX_DIRBLOCK_ROOT; 813 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST; 814 if ((root->reserved_zero || 815 root->info_length < 8 || 816 root->indirect_levels > 1) && 817 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) { 818 clear_htree(ctx, ino); 819 dx_dir->numblocks = 0; 820 dx_db = 0; 821 } 822 dx_dir->hashversion = root->hash_version; 823 if ((dx_dir->hashversion <= EXT2_HASH_TEA) && 824 (fs->super->s_flags & EXT2_FLAGS_UNSIGNED_HASH)) 825 dx_dir->hashversion += 3; 826 dx_dir->depth = root->indirect_levels + 1; 827 } else if ((dirent->inode == 0) && 828 (rec_len == fs->blocksize) && 829 (dirent->name_len == 0) && 830 (ext2fs_le16_to_cpu(limit->limit) == 831 ((fs->blocksize-8) / 832 sizeof(struct ext2_dx_entry)))) 833 dx_db->type = DX_DIRBLOCK_NODE; 834 } 835 out_htree: 836 #endif /* ENABLE_HTREE */ 837 838 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp); 839 prev = 0; 840 do { 841 int group; 842 ext2_ino_t first_unused_inode; 843 844 problem = 0; 845 dirent = (struct ext2_dir_entry *) (buf + offset); 846 (void) ext2fs_get_rec_len(fs, dirent, &rec_len); 847 cd->pctx.dirent = dirent; 848 cd->pctx.num = offset; 849 if (((offset + rec_len) > fs->blocksize) || 850 (rec_len < 12) || 851 ((rec_len % 4) != 0) || 852 (((dirent->name_len & (unsigned) 0xFF)+8) > rec_len)) { 853 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) { 854 salvage_directory(fs, dirent, prev, &offset); 855 dir_modified++; 856 continue; 857 } else 858 goto abort_free_dict; 859 } 860 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) { 861 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) { 862 dirent->name_len = EXT2_NAME_LEN; 863 dir_modified++; 864 } 865 } 866 867 if (dot_state == 0) { 868 if (check_dot(ctx, dirent, ino, &cd->pctx)) 869 dir_modified++; 870 } else if (dot_state == 1) { 871 ret = check_dotdot(ctx, dirent, ino, &cd->pctx); 872 if (ret < 0) 873 goto abort_free_dict; 874 if (ret) 875 dir_modified++; 876 } else if (dirent->inode == ino) { 877 problem = PR_2_LINK_DOT; 878 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) { 879 dirent->inode = 0; 880 dir_modified++; 881 goto next; 882 } 883 } 884 if (!dirent->inode) 885 goto next; 886 887 /* 888 * Make sure the inode listed is a legal one. 889 */ 890 if (((dirent->inode != EXT2_ROOT_INO) && 891 (dirent->inode < EXT2_FIRST_INODE(fs->super))) || 892 (dirent->inode > fs->super->s_inodes_count)) { 893 problem = PR_2_BAD_INO; 894 } else if (ctx->inode_bb_map && 895 (ext2fs_test_inode_bitmap(ctx->inode_bb_map, 896 dirent->inode))) { 897 /* 898 * If the inode is in a bad block, offer to 899 * clear it. 900 */ 901 problem = PR_2_BB_INODE; 902 } else if ((dot_state > 1) && 903 ((dirent->name_len & 0xFF) == 1) && 904 (dirent->name[0] == '.')) { 905 /* 906 * If there's a '.' entry in anything other 907 * than the first directory entry, it's a 908 * duplicate entry that should be removed. 909 */ 910 problem = PR_2_DUP_DOT; 911 } else if ((dot_state > 1) && 912 ((dirent->name_len & 0xFF) == 2) && 913 (dirent->name[0] == '.') && 914 (dirent->name[1] == '.')) { 915 /* 916 * If there's a '..' entry in anything other 917 * than the second directory entry, it's a 918 * duplicate entry that should be removed. 919 */ 920 problem = PR_2_DUP_DOT_DOT; 921 } else if ((dot_state > 1) && 922 (dirent->inode == EXT2_ROOT_INO)) { 923 /* 924 * Don't allow links to the root directory. 925 * We check this specially to make sure we 926 * catch this error case even if the root 927 * directory hasn't been created yet. 928 */ 929 problem = PR_2_LINK_ROOT; 930 } else if ((dot_state > 1) && 931 (dirent->name_len & 0xFF) == 0) { 932 /* 933 * Don't allow zero-length directory names. 934 */ 935 problem = PR_2_NULL_NAME; 936 } 937 938 if (problem) { 939 if (fix_problem(ctx, problem, &cd->pctx)) { 940 dirent->inode = 0; 941 dir_modified++; 942 goto next; 943 } else { 944 ext2fs_unmark_valid(fs); 945 if (problem == PR_2_BAD_INO) 946 goto next; 947 } 948 } 949 950 /* 951 * If the inode was marked as having bad fields in 952 * pass1, process it and offer to fix/clear it. 953 * (We wait until now so that we can display the 954 * pathname to the user.) 955 */ 956 if (ctx->inode_bad_map && 957 ext2fs_test_inode_bitmap(ctx->inode_bad_map, 958 dirent->inode)) { 959 if (e2fsck_process_bad_inode(ctx, ino, 960 dirent->inode, 961 buf + fs->blocksize)) { 962 dirent->inode = 0; 963 dir_modified++; 964 goto next; 965 } 966 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 967 return DIRENT_ABORT; 968 } 969 970 group = ext2fs_group_of_ino(fs, dirent->inode); 971 first_unused_inode = group * fs->super->s_inodes_per_group + 972 1 + fs->super->s_inodes_per_group - 973 fs->group_desc[group].bg_itable_unused; 974 cd->pctx.group = group; 975 976 /* 977 * Check if the inode was missed out because 978 * _INODE_UNINIT flag was set or bg_itable_unused was 979 * incorrect. If so, clear the _INODE_UNINIT flag and 980 * restart e2fsck. In the future it would be nice if 981 * we could call a function in pass1.c that checks the 982 * newly visible inodes. 983 */ 984 if (fs->group_desc[group].bg_flags & EXT2_BG_INODE_UNINIT) { 985 pctx.num = dirent->inode; 986 if (fix_problem(ctx, PR_2_INOREF_BG_INO_UNINIT, 987 &cd->pctx)){ 988 fs->group_desc[group].bg_flags &= 989 ~EXT2_BG_INODE_UNINIT; 990 ext2fs_mark_super_dirty(fs); 991 ctx->flags |= E2F_FLAG_RESTART_LATER; 992 } else { 993 ext2fs_unmark_valid(fs); 994 if (problem == PR_2_BAD_INO) 995 goto next; 996 } 997 } else if (dirent->inode >= first_unused_inode) { 998 pctx.num = dirent->inode; 999 if (fix_problem(ctx, PR_2_INOREF_IN_UNUSED, &cd->pctx)){ 1000 fs->group_desc[group].bg_itable_unused = 0; 1001 ext2fs_mark_super_dirty(fs); 1002 ctx->flags |= E2F_FLAG_RESTART_LATER; 1003 } else { 1004 ext2fs_unmark_valid(fs); 1005 if (problem == PR_2_BAD_INO) 1006 goto next; 1007 } 1008 } 1009 1010 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, 1011 dirent->inode))) { 1012 /* 1013 * If the inode is unused, offer to clear it. 1014 */ 1015 problem = PR_2_UNUSED_INODE; 1016 } 1017 1018 if (problem) { 1019 if (fix_problem(ctx, problem, &cd->pctx)) { 1020 dirent->inode = 0; 1021 dir_modified++; 1022 goto next; 1023 } else { 1024 ext2fs_unmark_valid(fs); 1025 if (problem == PR_2_BAD_INO) 1026 goto next; 1027 } 1028 } 1029 1030 if (check_name(ctx, dirent, ino, &cd->pctx)) 1031 dir_modified++; 1032 1033 if (check_filetype(ctx, dirent, ino, &cd->pctx)) 1034 dir_modified++; 1035 1036 #ifdef ENABLE_HTREE 1037 if (dx_db) { 1038 ext2fs_dirhash(dx_dir->hashversion, dirent->name, 1039 (dirent->name_len & 0xFF), 1040 fs->super->s_hash_seed, &hash, 0); 1041 if (hash < dx_db->min_hash) 1042 dx_db->min_hash = hash; 1043 if (hash > dx_db->max_hash) 1044 dx_db->max_hash = hash; 1045 } 1046 #endif 1047 1048 /* 1049 * If this is a directory, then mark its parent in its 1050 * dir_info structure. If the parent field is already 1051 * filled in, then this directory has more than one 1052 * hard link. We assume the first link is correct, 1053 * and ask the user if he/she wants to clear this one. 1054 */ 1055 if ((dot_state > 1) && 1056 (ext2fs_test_inode_bitmap(ctx->inode_dir_map, 1057 dirent->inode))) { 1058 if (e2fsck_dir_info_get_parent(ctx, dirent->inode, 1059 &subdir_parent)) { 1060 cd->pctx.ino = dirent->inode; 1061 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx); 1062 goto abort_free_dict; 1063 } 1064 if (subdir_parent) { 1065 cd->pctx.ino2 = subdir_parent; 1066 if (fix_problem(ctx, PR_2_LINK_DIR, 1067 &cd->pctx)) { 1068 dirent->inode = 0; 1069 dir_modified++; 1070 goto next; 1071 } 1072 cd->pctx.ino2 = 0; 1073 } else { 1074 (void) e2fsck_dir_info_set_parent(ctx, 1075 dirent->inode, ino); 1076 } 1077 } 1078 1079 if (dups_found) { 1080 ; 1081 } else if (dict_lookup(&de_dict, dirent)) { 1082 clear_problem_context(&pctx); 1083 pctx.ino = ino; 1084 pctx.dirent = dirent; 1085 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx); 1086 if (!ctx->dirs_to_hash) 1087 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50); 1088 if (ctx->dirs_to_hash) 1089 ext2fs_u32_list_add(ctx->dirs_to_hash, ino); 1090 dups_found++; 1091 } else 1092 dict_alloc_insert(&de_dict, dirent, dirent); 1093 1094 ext2fs_icount_increment(ctx->inode_count, dirent->inode, 1095 &links); 1096 if (links > 1) 1097 ctx->fs_links_count++; 1098 ctx->fs_total_count++; 1099 next: 1100 prev = dirent; 1101 if (dir_modified) 1102 (void) ext2fs_get_rec_len(fs, dirent, &rec_len); 1103 offset += rec_len; 1104 dot_state++; 1105 } while (offset < fs->blocksize); 1106 #if 0 1107 printf("\n"); 1108 #endif 1109 #ifdef ENABLE_HTREE 1110 if (dx_db) { 1111 #ifdef DX_DEBUG 1112 printf("db_block %d, type %d, min_hash 0x%0x, max_hash 0x%0x\n", 1113 db->blockcnt, dx_db->type, 1114 dx_db->min_hash, dx_db->max_hash); 1115 #endif 1116 cd->pctx.dir = cd->pctx.ino; 1117 if ((dx_db->type == DX_DIRBLOCK_ROOT) || 1118 (dx_db->type == DX_DIRBLOCK_NODE)) 1119 parse_int_node(fs, db, cd, dx_dir, buf); 1120 } 1121 #endif /* ENABLE_HTREE */ 1122 if (offset != fs->blocksize) { 1123 cd->pctx.num = rec_len - fs->blocksize + offset; 1124 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) { 1125 dirent->rec_len = cd->pctx.num; 1126 dir_modified++; 1127 } 1128 } 1129 if (dir_modified) { 1130 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf); 1131 if (cd->pctx.errcode) { 1132 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK, 1133 &cd->pctx)) 1134 goto abort_free_dict; 1135 } 1136 ext2fs_mark_changed(fs); 1137 } 1138 dict_free_nodes(&de_dict); 1139 return 0; 1140 abort_free_dict: 1141 ctx->flags |= E2F_FLAG_ABORT; 1142 dict_free_nodes(&de_dict); 1143 return DIRENT_ABORT; 1144 } 1145 1146 /* 1147 * This function is called to deallocate a block, and is an interator 1148 * functioned called by deallocate inode via ext2fs_iterate_block(). 1149 */ 1150 static int deallocate_inode_block(ext2_filsys fs, 1151 blk_t *block_nr, 1152 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), 1153 blk_t ref_block EXT2FS_ATTR((unused)), 1154 int ref_offset EXT2FS_ATTR((unused)), 1155 void *priv_data) 1156 { 1157 e2fsck_t ctx = (e2fsck_t) priv_data; 1158 1159 if (HOLE_BLKADDR(*block_nr)) 1160 return 0; 1161 if ((*block_nr < fs->super->s_first_data_block) || 1162 (*block_nr >= fs->super->s_blocks_count)) 1163 return 0; 1164 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr); 1165 ext2fs_block_alloc_stats(fs, *block_nr, -1); 1166 return 0; 1167 } 1168 1169 /* 1170 * This fuction deallocates an inode 1171 */ 1172 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf) 1173 { 1174 ext2_filsys fs = ctx->fs; 1175 struct ext2_inode inode; 1176 struct problem_context pctx; 1177 __u32 count; 1178 1179 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode"); 1180 e2fsck_clear_inode(ctx, ino, &inode, 0, "deallocate_inode"); 1181 clear_problem_context(&pctx); 1182 pctx.ino = ino; 1183 1184 /* 1185 * Fix up the bitmaps... 1186 */ 1187 e2fsck_read_bitmaps(ctx); 1188 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode)); 1189 1190 if (inode.i_file_acl && 1191 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) { 1192 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl, 1193 block_buf, -1, &count); 1194 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) { 1195 pctx.errcode = 0; 1196 count = 1; 1197 } 1198 if (pctx.errcode) { 1199 pctx.blk = inode.i_file_acl; 1200 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx); 1201 ctx->flags |= E2F_FLAG_ABORT; 1202 return; 1203 } 1204 if (count == 0) { 1205 ext2fs_unmark_block_bitmap(ctx->block_found_map, 1206 inode.i_file_acl); 1207 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1); 1208 } 1209 inode.i_file_acl = 0; 1210 } 1211 1212 if (!ext2fs_inode_has_valid_blocks(&inode)) 1213 return; 1214 1215 if (LINUX_S_ISREG(inode.i_mode) && 1216 (inode.i_size_high || inode.i_size & 0x80000000UL)) 1217 ctx->large_files--; 1218 1219 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, 1220 deallocate_inode_block, ctx); 1221 if (pctx.errcode) { 1222 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx); 1223 ctx->flags |= E2F_FLAG_ABORT; 1224 return; 1225 } 1226 } 1227 1228 /* 1229 * This fuction clears the htree flag on an inode 1230 */ 1231 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino) 1232 { 1233 struct ext2_inode inode; 1234 1235 e2fsck_read_inode(ctx, ino, &inode, "clear_htree"); 1236 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL; 1237 e2fsck_write_inode(ctx, ino, &inode, "clear_htree"); 1238 if (ctx->dirs_to_hash) 1239 ext2fs_u32_list_add(ctx->dirs_to_hash, ino); 1240 } 1241 1242 1243 extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, 1244 ext2_ino_t ino, char *buf) 1245 { 1246 ext2_filsys fs = ctx->fs; 1247 struct ext2_inode inode; 1248 int inode_modified = 0; 1249 int not_fixed = 0; 1250 unsigned char *frag, *fsize; 1251 struct problem_context pctx; 1252 int problem = 0; 1253 1254 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode"); 1255 1256 clear_problem_context(&pctx); 1257 pctx.ino = ino; 1258 pctx.dir = dir; 1259 pctx.inode = &inode; 1260 1261 if (inode.i_file_acl && 1262 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) { 1263 if (fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) { 1264 inode.i_file_acl = 0; 1265 inode_modified++; 1266 } else 1267 not_fixed++; 1268 } 1269 1270 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) && 1271 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) && 1272 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) && 1273 !(LINUX_S_ISSOCK(inode.i_mode))) 1274 problem = PR_2_BAD_MODE; 1275 else if (LINUX_S_ISCHR(inode.i_mode) 1276 && !e2fsck_pass1_check_device_inode(fs, &inode)) 1277 problem = PR_2_BAD_CHAR_DEV; 1278 else if (LINUX_S_ISBLK(inode.i_mode) 1279 && !e2fsck_pass1_check_device_inode(fs, &inode)) 1280 problem = PR_2_BAD_BLOCK_DEV; 1281 else if (LINUX_S_ISFIFO(inode.i_mode) 1282 && !e2fsck_pass1_check_device_inode(fs, &inode)) 1283 problem = PR_2_BAD_FIFO; 1284 else if (LINUX_S_ISSOCK(inode.i_mode) 1285 && !e2fsck_pass1_check_device_inode(fs, &inode)) 1286 problem = PR_2_BAD_SOCKET; 1287 else if (LINUX_S_ISLNK(inode.i_mode) 1288 && !e2fsck_pass1_check_symlink(fs, ino, &inode, buf)) { 1289 problem = PR_2_INVALID_SYMLINK; 1290 } 1291 1292 if (problem) { 1293 if (fix_problem(ctx, problem, &pctx)) { 1294 deallocate_inode(ctx, ino, 0); 1295 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 1296 return 0; 1297 return 1; 1298 } else 1299 not_fixed++; 1300 problem = 0; 1301 } 1302 1303 if (inode.i_faddr) { 1304 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) { 1305 inode.i_faddr = 0; 1306 inode_modified++; 1307 } else 1308 not_fixed++; 1309 } 1310 1311 switch (fs->super->s_creator_os) { 1312 case EXT2_OS_HURD: 1313 frag = &inode.osd2.hurd2.h_i_frag; 1314 fsize = &inode.osd2.hurd2.h_i_fsize; 1315 break; 1316 default: 1317 frag = fsize = 0; 1318 } 1319 if (frag && *frag) { 1320 pctx.num = *frag; 1321 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) { 1322 *frag = 0; 1323 inode_modified++; 1324 } else 1325 not_fixed++; 1326 pctx.num = 0; 1327 } 1328 if (fsize && *fsize) { 1329 pctx.num = *fsize; 1330 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) { 1331 *fsize = 0; 1332 inode_modified++; 1333 } else 1334 not_fixed++; 1335 pctx.num = 0; 1336 } 1337 1338 if ((fs->super->s_creator_os == EXT2_OS_LINUX) && 1339 !(fs->super->s_feature_ro_compat & 1340 EXT4_FEATURE_RO_COMPAT_HUGE_FILE) && 1341 (inode.osd2.linux2.l_i_blocks_hi != 0)) { 1342 pctx.num = inode.osd2.linux2.l_i_blocks_hi; 1343 if (fix_problem(ctx, PR_2_BLOCKS_HI_ZERO, &pctx)) { 1344 inode.osd2.linux2.l_i_blocks_hi = 0; 1345 inode_modified++; 1346 } 1347 } 1348 1349 if (!(fs->super->s_feature_incompat & 1350 EXT4_FEATURE_INCOMPAT_64BIT) && 1351 inode.osd2.linux2.l_i_file_acl_high != 0) { 1352 pctx.num = inode.osd2.linux2.l_i_file_acl_high; 1353 if (fix_problem(ctx, PR_2_I_FILE_ACL_HI_ZERO, &pctx)) { 1354 inode.osd2.linux2.l_i_file_acl_high = 0; 1355 inode_modified++; 1356 } else 1357 not_fixed++; 1358 } 1359 1360 if (inode.i_file_acl && 1361 ((inode.i_file_acl < fs->super->s_first_data_block) || 1362 (inode.i_file_acl >= fs->super->s_blocks_count))) { 1363 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) { 1364 inode.i_file_acl = 0; 1365 inode_modified++; 1366 } else 1367 not_fixed++; 1368 } 1369 if (inode.i_dir_acl && 1370 LINUX_S_ISDIR(inode.i_mode)) { 1371 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) { 1372 inode.i_dir_acl = 0; 1373 inode_modified++; 1374 } else 1375 not_fixed++; 1376 } 1377 1378 if (inode_modified) 1379 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode"); 1380 if (!not_fixed && ctx->inode_bad_map) 1381 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino); 1382 return 0; 1383 } 1384 1385 1386 /* 1387 * allocate_dir_block --- this function allocates a new directory 1388 * block for a particular inode; this is done if a directory has 1389 * a "hole" in it, or if a directory has a illegal block number 1390 * that was zeroed out and now needs to be replaced. 1391 */ 1392 static int allocate_dir_block(e2fsck_t ctx, 1393 struct ext2_db_entry *db, 1394 char *buf EXT2FS_ATTR((unused)), 1395 struct problem_context *pctx) 1396 { 1397 ext2_filsys fs = ctx->fs; 1398 blk_t blk; 1399 char *block; 1400 struct ext2_inode inode; 1401 1402 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0) 1403 return 1; 1404 1405 /* 1406 * Read the inode and block bitmaps in; we'll be messing with 1407 * them. 1408 */ 1409 e2fsck_read_bitmaps(ctx); 1410 1411 /* 1412 * First, find a free block 1413 */ 1414 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk); 1415 if (pctx->errcode) { 1416 pctx->str = "ext2fs_new_block"; 1417 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); 1418 return 1; 1419 } 1420 ext2fs_mark_block_bitmap(ctx->block_found_map, blk); 1421 ext2fs_mark_block_bitmap(fs->block_map, blk); 1422 ext2fs_mark_bb_dirty(fs); 1423 1424 /* 1425 * Now let's create the actual data block for the inode 1426 */ 1427 if (db->blockcnt) 1428 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block); 1429 else 1430 pctx->errcode = ext2fs_new_dir_block(fs, db->ino, 1431 EXT2_ROOT_INO, &block); 1432 1433 if (pctx->errcode) { 1434 pctx->str = "ext2fs_new_dir_block"; 1435 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); 1436 return 1; 1437 } 1438 1439 pctx->errcode = ext2fs_write_dir_block(fs, blk, block); 1440 ext2fs_free_mem(&block); 1441 if (pctx->errcode) { 1442 pctx->str = "ext2fs_write_dir_block"; 1443 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); 1444 return 1; 1445 } 1446 1447 /* 1448 * Update the inode block count 1449 */ 1450 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block"); 1451 ext2fs_iblk_add_blocks(fs, &inode, 1); 1452 if (inode.i_size < (db->blockcnt+1) * fs->blocksize) 1453 inode.i_size = (db->blockcnt+1) * fs->blocksize; 1454 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block"); 1455 1456 /* 1457 * Finally, update the block pointers for the inode 1458 */ 1459 db->blk = blk; 1460 pctx->errcode = ext2fs_bmap(fs, db->ino, &inode, 0, BMAP_SET, 1461 db->blockcnt, &blk); 1462 if (pctx->errcode) { 1463 pctx->str = "ext2fs_block_iterate"; 1464 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); 1465 return 1; 1466 } 1467 1468 return 0; 1469 } 1470