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