pass5.c revision fd9ca825996d61ad7c77edded827c661a458b500
1/* 2 * pass5.c --- check block and inode bitmaps against on-disk bitmaps 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 */ 12 13#include "config.h" 14#include <stdint.h> 15#include <sys/types.h> 16#include <sys/stat.h> 17#include <sys/ioctl.h> 18#include <fcntl.h> 19#include <errno.h> 20 21#include "e2fsck.h" 22#include "problem.h" 23 24#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) 25 26static void check_block_bitmaps(e2fsck_t ctx); 27static void check_inode_bitmaps(e2fsck_t ctx); 28static void check_inode_end(e2fsck_t ctx); 29static void check_block_end(e2fsck_t ctx); 30static void check_inode_bitmap_checksum(e2fsck_t ctx); 31static void check_block_bitmap_checksum(e2fsck_t ctx); 32 33void e2fsck_pass5(e2fsck_t ctx) 34{ 35#ifdef RESOURCE_TRACK 36 struct resource_track rtrack; 37#endif 38 struct problem_context pctx; 39 40#ifdef MTRACE 41 mtrace_print("Pass 5"); 42#endif 43 44 init_resource_track(&rtrack, ctx->fs->io); 45 clear_problem_context(&pctx); 46 47 if (!(ctx->options & E2F_OPT_PREEN)) 48 fix_problem(ctx, PR_5_PASS_HEADER, &pctx); 49 50 if (ctx->progress) 51 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2)) 52 return; 53 54 e2fsck_read_bitmaps(ctx); 55 56 check_block_bitmaps(ctx); 57 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 58 return; 59 check_inode_bitmaps(ctx); 60 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 61 return; 62 check_inode_end(ctx); 63 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 64 return; 65 check_block_end(ctx); 66 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 67 return; 68 69 check_inode_bitmap_checksum(ctx); 70 check_block_bitmap_checksum(ctx); 71 72 ext2fs_free_inode_bitmap(ctx->inode_used_map); 73 ctx->inode_used_map = 0; 74 ext2fs_free_inode_bitmap(ctx->inode_dir_map); 75 ctx->inode_dir_map = 0; 76 ext2fs_free_block_bitmap(ctx->block_found_map); 77 ctx->block_found_map = 0; 78 79 print_resource_track(ctx, _("Pass 5"), &rtrack, ctx->fs->io); 80} 81 82static void check_inode_bitmap_checksum(e2fsck_t ctx) 83{ 84 struct problem_context pctx; 85 char *buf; 86 dgrp_t i; 87 int nbytes; 88 ext2_ino_t ino_itr; 89 errcode_t retval; 90 91 if (!EXT2_HAS_RO_COMPAT_FEATURE(ctx->fs->super, 92 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 93 return; 94 95 /* If bitmap is dirty from being fixed, checksum will be corrected */ 96 if (ext2fs_test_ib_dirty(ctx->fs)) 97 return; 98 99 nbytes = (size_t)(EXT2_INODES_PER_GROUP(ctx->fs->super) / 8); 100 retval = ext2fs_get_memalign(ctx->fs->blocksize, ctx->fs->blocksize, 101 &buf); 102 if (retval) { 103 com_err(ctx->program_name, 0, 104 _("check_inode_bitmap_checksum: Memory allocation error")); 105 fatal_error(ctx, 0); 106 } 107 108 clear_problem_context(&pctx); 109 for (i = 0; i < ctx->fs->group_desc_count; i++) { 110 if (ext2fs_bg_flags_test(ctx->fs, i, EXT2_BG_INODE_UNINIT)) 111 continue; 112 113 ino_itr = 1 + (i * (nbytes << 3)); 114 retval = ext2fs_get_inode_bitmap_range2(ctx->fs->inode_map, 115 ino_itr, nbytes << 3, 116 buf); 117 if (retval) 118 break; 119 120 if (ext2fs_inode_bitmap_csum_verify(ctx->fs, i, buf, nbytes)) 121 continue; 122 pctx.group = i; 123 if (!fix_problem(ctx, PR_5_INODE_BITMAP_CSUM_INVALID, &pctx)) 124 continue; 125 126 /* 127 * Fixing one checksum will rewrite all of them. The bitmap 128 * will be checked against the one we made during pass1 for 129 * discrepancies, and fixed if need be. 130 */ 131 ext2fs_mark_ib_dirty(ctx->fs); 132 break; 133 } 134 135 ext2fs_free_mem(&buf); 136} 137 138static void check_block_bitmap_checksum(e2fsck_t ctx) 139{ 140 struct problem_context pctx; 141 char *buf; 142 dgrp_t i; 143 int nbytes; 144 blk64_t blk_itr; 145 errcode_t retval; 146 147 if (!EXT2_HAS_RO_COMPAT_FEATURE(ctx->fs->super, 148 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) 149 return; 150 151 /* If bitmap is dirty from being fixed, checksum will be corrected */ 152 if (ext2fs_test_bb_dirty(ctx->fs)) 153 return; 154 155 nbytes = (size_t)(EXT2_CLUSTERS_PER_GROUP(ctx->fs->super) / 8); 156 retval = ext2fs_get_memalign(ctx->fs->blocksize, ctx->fs->blocksize, 157 &buf); 158 if (retval) { 159 com_err(ctx->program_name, 0, 160 _("check_block_bitmap_checksum: Memory allocation error")); 161 fatal_error(ctx, 0); 162 } 163 164 clear_problem_context(&pctx); 165 for (i = 0; i < ctx->fs->group_desc_count; i++) { 166 if (ext2fs_bg_flags_test(ctx->fs, i, EXT2_BG_BLOCK_UNINIT)) 167 continue; 168 169 blk_itr = EXT2FS_B2C(ctx->fs, 170 ctx->fs->super->s_first_data_block) + 171 (i * (nbytes << 3)); 172 retval = ext2fs_get_block_bitmap_range2(ctx->fs->block_map, 173 blk_itr, nbytes << 3, 174 buf); 175 if (retval) 176 break; 177 178 if (ext2fs_block_bitmap_csum_verify(ctx->fs, i, buf, nbytes)) 179 continue; 180 pctx.group = i; 181 if (!fix_problem(ctx, PR_5_BLOCK_BITMAP_CSUM_INVALID, &pctx)) 182 continue; 183 184 /* 185 * Fixing one checksum will rewrite all of them. The bitmap 186 * will be checked against the one we made during pass1 for 187 * discrepancies, and fixed if need be. 188 */ 189 ext2fs_mark_bb_dirty(ctx->fs); 190 break; 191 } 192 193 ext2fs_free_mem(&buf); 194} 195 196static void e2fsck_discard_blocks(e2fsck_t ctx, blk64_t start, 197 blk64_t count) 198{ 199 ext2_filsys fs = ctx->fs; 200 201 /* 202 * If the filesystem has changed it means that there was an corruption 203 * which should be repaired, but in some cases just one e2fsck run is 204 * not enough to fix the problem, hence it is not safe to run discard 205 * in this case. 206 */ 207 if (ext2fs_test_changed(fs)) 208 ctx->options &= ~E2F_OPT_DISCARD; 209 210 if ((ctx->options & E2F_OPT_DISCARD) && 211 (io_channel_discard(fs->io, start, count))) 212 ctx->options &= ~E2F_OPT_DISCARD; 213} 214 215/* 216 * This will try to discard number 'count' inodes starting at 217 * inode number 'start' within the 'group'. Note that 'start' 218 * is 1-based, it means that we need to adjust it by -1 in this 219 * function to compute right offset in the particular inode table. 220 */ 221static void e2fsck_discard_inodes(e2fsck_t ctx, dgrp_t group, 222 ext2_ino_t start, int count) 223{ 224 ext2_filsys fs = ctx->fs; 225 blk64_t blk, num; 226 227 /* 228 * Sanity check for 'start' 229 */ 230 if ((start < 1) || (start > EXT2_INODES_PER_GROUP(fs->super))) { 231 printf("PROGRAMMING ERROR: Got start %d outside of group %d!" 232 " Disabling discard\n", 233 start, group); 234 ctx->options &= ~E2F_OPT_DISCARD; 235 } 236 237 /* 238 * Do not attempt to discard if E2F_OPT_DISCARD is not set. And also 239 * skip the discard on this group if discard does not zero data. 240 * The reason is that if the inode table is not zeroed discard would 241 * no help us since we need to zero it anyway, or if the inode table 242 * is zeroed then the read after discard would not be deterministic 243 * anyway and we would not be able to assume that this inode table 244 * was zeroed anymore so we would have to zero it again, which does 245 * not really make sense. 246 */ 247 if (!(ctx->options & E2F_OPT_DISCARD) || 248 !io_channel_discard_zeroes_data(fs->io)) 249 return; 250 251 /* 252 * Start is inode number within the group which starts 253 * counting from 1, so we need to adjust it. 254 */ 255 start -= 1; 256 257 /* 258 * We can discard only blocks containing only unused 259 * inodes in the table. 260 */ 261 blk = DIV_ROUND_UP(start, 262 EXT2_INODES_PER_BLOCK(fs->super)); 263 count -= (blk * EXT2_INODES_PER_BLOCK(fs->super) - start); 264 blk += ext2fs_inode_table_loc(fs, group); 265 num = count / EXT2_INODES_PER_BLOCK(fs->super); 266 267 if (num > 0) 268 e2fsck_discard_blocks(ctx, blk, num); 269} 270 271#define NO_BLK ((blk64_t) -1) 272 273static void print_bitmap_problem(e2fsck_t ctx, int problem, 274 struct problem_context *pctx) 275{ 276 switch (problem) { 277 case PR_5_BLOCK_UNUSED: 278 if (pctx->blk == pctx->blk2) 279 pctx->blk2 = 0; 280 else 281 problem = PR_5_BLOCK_RANGE_UNUSED; 282 break; 283 case PR_5_BLOCK_USED: 284 if (pctx->blk == pctx->blk2) 285 pctx->blk2 = 0; 286 else 287 problem = PR_5_BLOCK_RANGE_USED; 288 break; 289 case PR_5_INODE_UNUSED: 290 if (pctx->ino == pctx->ino2) 291 pctx->ino2 = 0; 292 else 293 problem = PR_5_INODE_RANGE_UNUSED; 294 break; 295 case PR_5_INODE_USED: 296 if (pctx->ino == pctx->ino2) 297 pctx->ino2 = 0; 298 else 299 problem = PR_5_INODE_RANGE_USED; 300 break; 301 } 302 fix_problem(ctx, problem, pctx); 303 pctx->blk = pctx->blk2 = NO_BLK; 304 pctx->ino = pctx->ino2 = 0; 305} 306 307/* Just to be more succint */ 308#define B2C(x) EXT2FS_B2C(fs, (x)) 309#define EQ_CLSTR(x, y) (B2C(x) == B2C(y)) 310#define LE_CLSTR(x, y) (B2C(x) <= B2C(y)) 311#define GE_CLSTR(x, y) (B2C(x) >= B2C(y)) 312 313static void check_block_bitmaps(e2fsck_t ctx) 314{ 315 ext2_filsys fs = ctx->fs; 316 blk64_t i; 317 unsigned int *free_array; 318 int group = 0; 319 unsigned int blocks = 0; 320 blk64_t free_blocks = 0; 321 blk64_t first_free = ext2fs_blocks_count(fs->super); 322 unsigned int group_free = 0; 323 int actual, bitmap; 324 struct problem_context pctx; 325 int problem, save_problem, fixit, had_problem; 326 errcode_t retval; 327 int csum_flag; 328 int skip_group = 0; 329 int old_desc_blocks = 0; 330 int count = 0; 331 int cmp_block = 0; 332 int redo_flag = 0; 333 blk64_t super_blk, old_desc_blk, new_desc_blk; 334 char *actual_buf, *bitmap_buf; 335 336 actual_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize, 337 "actual bitmap buffer"); 338 bitmap_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize, 339 "bitmap block buffer"); 340 341 clear_problem_context(&pctx); 342 free_array = (unsigned int *) e2fsck_allocate_memory(ctx, 343 fs->group_desc_count * sizeof(unsigned int), "free block count array"); 344 345 if ((B2C(fs->super->s_first_data_block) < 346 ext2fs_get_block_bitmap_start2(ctx->block_found_map)) || 347 (B2C(ext2fs_blocks_count(fs->super)-1) > 348 ext2fs_get_block_bitmap_end2(ctx->block_found_map))) { 349 pctx.num = 1; 350 pctx.blk = B2C(fs->super->s_first_data_block); 351 pctx.blk2 = B2C(ext2fs_blocks_count(fs->super) - 1); 352 pctx.ino = ext2fs_get_block_bitmap_start2(ctx->block_found_map); 353 pctx.ino2 = ext2fs_get_block_bitmap_end2(ctx->block_found_map); 354 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); 355 356 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 357 goto errout; 358 } 359 360 if ((B2C(fs->super->s_first_data_block) < 361 ext2fs_get_block_bitmap_start2(fs->block_map)) || 362 (B2C(ext2fs_blocks_count(fs->super)-1) > 363 ext2fs_get_block_bitmap_end2(fs->block_map))) { 364 pctx.num = 2; 365 pctx.blk = B2C(fs->super->s_first_data_block); 366 pctx.blk2 = B2C(ext2fs_blocks_count(fs->super) - 1); 367 pctx.ino = ext2fs_get_block_bitmap_start2(fs->block_map); 368 pctx.ino2 = ext2fs_get_block_bitmap_end2(fs->block_map); 369 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); 370 371 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 372 goto errout; 373 } 374 375 csum_flag = ext2fs_has_group_desc_csum(fs); 376redo_counts: 377 had_problem = 0; 378 save_problem = 0; 379 pctx.blk = pctx.blk2 = NO_BLK; 380 if (csum_flag && 381 (ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT))) 382 skip_group++; 383 for (i = B2C(fs->super->s_first_data_block); 384 i < ext2fs_blocks_count(fs->super); 385 i += EXT2FS_CLUSTER_RATIO(fs)) { 386 int first_block_in_bg = (B2C(i) - 387 B2C(fs->super->s_first_data_block)) % 388 fs->super->s_clusters_per_group == 0; 389 int n, nbytes = fs->super->s_clusters_per_group / 8; 390 391 actual = ext2fs_fast_test_block_bitmap2(ctx->block_found_map, i); 392 393 /* 394 * Try to optimize pass5 by extracting a bitmap block 395 * as expected from what we have on disk, and then 396 * comparing the two. If they are identical, then 397 * update the free block counts and go on to the next 398 * block group. This is much faster than doing the 399 * individual bit-by-bit comparison. The one downside 400 * is that this doesn't work if we are asking e2fsck 401 * to do a discard operation. 402 */ 403 if (!first_block_in_bg || 404 (group == (int)fs->group_desc_count - 1) || 405 (ctx->options & E2F_OPT_DISCARD)) 406 goto no_optimize; 407 408 retval = ext2fs_get_block_bitmap_range2(ctx->block_found_map, 409 B2C(i), fs->super->s_clusters_per_group, 410 actual_buf); 411 if (retval) 412 goto no_optimize; 413 if (ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT)) 414 memset(bitmap_buf, 0, nbytes); 415 else { 416 retval = ext2fs_get_block_bitmap_range2(fs->block_map, 417 B2C(i), fs->super->s_clusters_per_group, 418 bitmap_buf); 419 if (retval) 420 goto no_optimize; 421 } 422 if (memcmp(actual_buf, bitmap_buf, nbytes) != 0) 423 goto no_optimize; 424 n = ext2fs_bitcount(actual_buf, nbytes); 425 group_free = fs->super->s_clusters_per_group - n; 426 free_blocks += group_free; 427 i += EXT2FS_C2B(fs, fs->super->s_clusters_per_group - 1); 428 goto next_group; 429 no_optimize: 430 431 if (skip_group) { 432 if (first_block_in_bg) { 433 super_blk = 0; 434 old_desc_blk = 0; 435 new_desc_blk = 0; 436 ext2fs_super_and_bgd_loc2(fs, group, &super_blk, 437 &old_desc_blk, &new_desc_blk, 0); 438 439 if (fs->super->s_feature_incompat & 440 EXT2_FEATURE_INCOMPAT_META_BG) 441 old_desc_blocks = 442 fs->super->s_first_meta_bg; 443 else 444 old_desc_blocks = fs->desc_blocks + 445 fs->super->s_reserved_gdt_blocks; 446 447 count = 0; 448 cmp_block = fs->super->s_clusters_per_group; 449 if (group == (int)fs->group_desc_count - 1) 450 cmp_block = EXT2FS_NUM_B2C(fs, 451 ext2fs_group_blocks_count(fs, group)); 452 } 453 454 bitmap = 0; 455 if (EQ_CLSTR(i, super_blk) || 456 (old_desc_blk && old_desc_blocks && 457 GE_CLSTR(i, old_desc_blk) && 458 LE_CLSTR(i, old_desc_blk + old_desc_blocks-1)) || 459 (new_desc_blk && EQ_CLSTR(i, new_desc_blk)) || 460 EQ_CLSTR(i, ext2fs_block_bitmap_loc(fs, group)) || 461 EQ_CLSTR(i, ext2fs_inode_bitmap_loc(fs, group)) || 462 (GE_CLSTR(i, ext2fs_inode_table_loc(fs, group)) && 463 LE_CLSTR(i, (ext2fs_inode_table_loc(fs, group) + 464 fs->inode_blocks_per_group - 1)))) { 465 bitmap = 1; 466 actual = (actual != 0); 467 count++; 468 cmp_block--; 469 } else if ((EXT2FS_B2C(fs, i) - count - 470 EXT2FS_B2C(fs, fs->super->s_first_data_block)) % 471 fs->super->s_clusters_per_group == 0) { 472 /* 473 * When the compare data blocks in block bitmap 474 * are 0, count the free block, 475 * skip the current block group. 476 */ 477 if (ext2fs_test_block_bitmap_range2( 478 ctx->block_found_map, 479 EXT2FS_B2C(fs, i), 480 cmp_block)) { 481 /* 482 * -1 means to skip the current block 483 * group. 484 */ 485 blocks = fs->super->s_clusters_per_group - 1; 486 group_free = cmp_block; 487 free_blocks += cmp_block; 488 /* 489 * The current block group's last block 490 * is set to i. 491 */ 492 i += EXT2FS_C2B(fs, cmp_block - 1); 493 bitmap = 1; 494 goto do_counts; 495 } 496 } 497 } else if (redo_flag) 498 bitmap = actual; 499 else 500 bitmap = ext2fs_fast_test_block_bitmap2(fs->block_map, i); 501 502 if (!actual == !bitmap) 503 goto do_counts; 504 505 if (!actual && bitmap) { 506 /* 507 * Block not used, but marked in use in the bitmap. 508 */ 509 problem = PR_5_BLOCK_UNUSED; 510 } else { 511 /* 512 * Block used, but not marked in use in the bitmap. 513 */ 514 problem = PR_5_BLOCK_USED; 515 516 if (skip_group) { 517 struct problem_context pctx2; 518 pctx2.blk = i; 519 pctx2.group = group; 520 if (fix_problem(ctx, PR_5_BLOCK_UNINIT,&pctx2)){ 521 ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT); 522 skip_group = 0; 523 } 524 } 525 } 526 if (pctx.blk == NO_BLK) { 527 pctx.blk = pctx.blk2 = i; 528 save_problem = problem; 529 } else { 530 if ((problem == save_problem) && 531 (pctx.blk2 == i-1)) 532 pctx.blk2++; 533 else { 534 print_bitmap_problem(ctx, save_problem, &pctx); 535 pctx.blk = pctx.blk2 = i; 536 save_problem = problem; 537 } 538 } 539 ctx->flags |= E2F_FLAG_PROG_SUPPRESS; 540 had_problem++; 541 542 /* 543 * If there a problem we should turn off the discard so we 544 * do not compromise the filesystem. 545 */ 546 ctx->options &= ~E2F_OPT_DISCARD; 547 548 do_counts: 549 if (!bitmap) { 550 group_free++; 551 free_blocks++; 552 if (first_free > i) 553 first_free = i; 554 } else if (i > first_free) { 555 e2fsck_discard_blocks(ctx, first_free, 556 (i - first_free)); 557 first_free = ext2fs_blocks_count(fs->super); 558 } 559 blocks ++; 560 if ((blocks == fs->super->s_clusters_per_group) || 561 (EXT2FS_B2C(fs, i) == 562 EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super)-1))) { 563 /* 564 * If the last block of this group is free, then we can 565 * discard it as well. 566 */ 567 if (!bitmap && i >= first_free) 568 e2fsck_discard_blocks(ctx, first_free, 569 (i - first_free) + 1); 570 next_group: 571 first_free = ext2fs_blocks_count(fs->super); 572 573 free_array[group] = group_free; 574 group ++; 575 blocks = 0; 576 group_free = 0; 577 skip_group = 0; 578 if (ctx->progress) 579 if ((ctx->progress)(ctx, 5, group, 580 fs->group_desc_count*2)) 581 goto errout; 582 if (csum_flag && 583 (i != ext2fs_blocks_count(fs->super)-1) && 584 ext2fs_bg_flags_test(fs, group, 585 EXT2_BG_BLOCK_UNINIT)) 586 skip_group++; 587 } 588 } 589 if (pctx.blk != NO_BLK) 590 print_bitmap_problem(ctx, save_problem, &pctx); 591 if (had_problem) 592 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP); 593 else 594 fixit = -1; 595 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS; 596 597 if (fixit == 1) { 598 ext2fs_free_block_bitmap(fs->block_map); 599 retval = ext2fs_copy_bitmap(ctx->block_found_map, 600 &fs->block_map); 601 if (retval) { 602 clear_problem_context(&pctx); 603 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx); 604 ctx->flags |= E2F_FLAG_ABORT; 605 goto errout; 606 } 607 ext2fs_set_bitmap_padding(fs->block_map); 608 ext2fs_mark_bb_dirty(fs); 609 610 /* Redo the counts */ 611 blocks = 0; free_blocks = 0; group_free = 0; group = 0; 612 memset(free_array, 0, fs->group_desc_count * sizeof(int)); 613 redo_flag++; 614 goto redo_counts; 615 } else if (fixit == 0) 616 ext2fs_unmark_valid(fs); 617 618 for (i = 0; i < fs->group_desc_count; i++) { 619 if (free_array[i] != ext2fs_bg_free_blocks_count(fs, i)) { 620 pctx.group = i; 621 pctx.blk = ext2fs_bg_free_blocks_count(fs, i); 622 pctx.blk2 = free_array[i]; 623 624 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP, 625 &pctx)) { 626 ext2fs_bg_free_blocks_count_set(fs, i, free_array[i]); 627 ext2fs_mark_super_dirty(fs); 628 } else 629 ext2fs_unmark_valid(fs); 630 } 631 } 632 free_blocks = EXT2FS_C2B(fs, free_blocks); 633 if (free_blocks != ext2fs_free_blocks_count(fs->super)) { 634 pctx.group = 0; 635 pctx.blk = ext2fs_free_blocks_count(fs->super); 636 pctx.blk2 = free_blocks; 637 638 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) { 639 ext2fs_free_blocks_count_set(fs->super, free_blocks); 640 ext2fs_mark_super_dirty(fs); 641 } 642 } 643errout: 644 ext2fs_free_mem(&free_array); 645 ext2fs_free_mem(&actual_buf); 646 ext2fs_free_mem(&bitmap_buf); 647} 648 649static void check_inode_bitmaps(e2fsck_t ctx) 650{ 651 ext2_filsys fs = ctx->fs; 652 ext2_ino_t i; 653 unsigned int free_inodes = 0; 654 int group_free = 0; 655 int dirs_count = 0; 656 int group = 0; 657 unsigned int inodes = 0; 658 ext2_ino_t *free_array; 659 ext2_ino_t *dir_array; 660 int actual, bitmap; 661 errcode_t retval; 662 struct problem_context pctx; 663 int problem, save_problem, fixit, had_problem; 664 int csum_flag; 665 int skip_group = 0; 666 int redo_flag = 0; 667 ext2_ino_t first_free = fs->super->s_inodes_per_group + 1; 668 669 clear_problem_context(&pctx); 670 free_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx, 671 fs->group_desc_count * sizeof(ext2_ino_t), "free inode count array"); 672 673 dir_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx, 674 fs->group_desc_count * sizeof(ext2_ino_t), "directory count array"); 675 676 if ((1 < ext2fs_get_inode_bitmap_start2(ctx->inode_used_map)) || 677 (fs->super->s_inodes_count > 678 ext2fs_get_inode_bitmap_end2(ctx->inode_used_map))) { 679 pctx.num = 3; 680 pctx.blk = 1; 681 pctx.blk2 = fs->super->s_inodes_count; 682 pctx.ino = ext2fs_get_inode_bitmap_start2(ctx->inode_used_map); 683 pctx.ino2 = ext2fs_get_inode_bitmap_end2(ctx->inode_used_map); 684 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); 685 686 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 687 goto errout; 688 } 689 if ((1 < ext2fs_get_inode_bitmap_start2(fs->inode_map)) || 690 (fs->super->s_inodes_count > 691 ext2fs_get_inode_bitmap_end2(fs->inode_map))) { 692 pctx.num = 4; 693 pctx.blk = 1; 694 pctx.blk2 = fs->super->s_inodes_count; 695 pctx.ino = ext2fs_get_inode_bitmap_start2(fs->inode_map); 696 pctx.ino2 = ext2fs_get_inode_bitmap_end2(fs->inode_map); 697 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); 698 699 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 700 goto errout; 701 } 702 703 csum_flag = ext2fs_has_group_desc_csum(fs); 704redo_counts: 705 had_problem = 0; 706 save_problem = 0; 707 pctx.ino = pctx.ino2 = 0; 708 if (csum_flag && 709 (ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT))) 710 skip_group++; 711 712 /* Protect loop from wrap-around if inodes_count is maxed */ 713 for (i = 1; i <= fs->super->s_inodes_count && i > 0; i++) { 714 bitmap = 0; 715 if (skip_group && 716 i % fs->super->s_inodes_per_group == 1) { 717 /* 718 * Current inode is the first inode 719 * in the current block group. 720 */ 721 if (ext2fs_test_inode_bitmap_range( 722 ctx->inode_used_map, i, 723 fs->super->s_inodes_per_group)) { 724 /* 725 * When the compared inodes in inodes bitmap 726 * are 0, count the free inode, 727 * skip the current block group. 728 */ 729 first_free = 1; 730 inodes = fs->super->s_inodes_per_group - 1; 731 group_free = inodes; 732 free_inodes += inodes; 733 i += inodes; 734 skip_group = 0; 735 goto do_counts; 736 } 737 } 738 739 actual = ext2fs_fast_test_inode_bitmap2(ctx->inode_used_map, i); 740 if (redo_flag) 741 bitmap = actual; 742 else if (!skip_group) 743 bitmap = ext2fs_fast_test_inode_bitmap2(fs->inode_map, i); 744 if (!actual == !bitmap) 745 goto do_counts; 746 747 if (!actual && bitmap) { 748 /* 749 * Inode wasn't used, but marked in bitmap 750 */ 751 problem = PR_5_INODE_UNUSED; 752 } else /* if (actual && !bitmap) */ { 753 /* 754 * Inode used, but not in bitmap 755 */ 756 problem = PR_5_INODE_USED; 757 758 /* We should never hit this, because it means that 759 * inodes were marked in use that weren't noticed 760 * in pass1 or pass 2. It is easier to fix the problem 761 * than to kill e2fsck and leave the user stuck. */ 762 if (skip_group) { 763 struct problem_context pctx2; 764 pctx2.blk = i; 765 pctx2.group = group; 766 if (fix_problem(ctx, PR_5_INODE_UNINIT,&pctx2)){ 767 ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT); 768 skip_group = 0; 769 } 770 } 771 } 772 if (pctx.ino == 0) { 773 pctx.ino = pctx.ino2 = i; 774 save_problem = problem; 775 } else { 776 if ((problem == save_problem) && 777 (pctx.ino2 == i-1)) 778 pctx.ino2++; 779 else { 780 print_bitmap_problem(ctx, save_problem, &pctx); 781 pctx.ino = pctx.ino2 = i; 782 save_problem = problem; 783 } 784 } 785 ctx->flags |= E2F_FLAG_PROG_SUPPRESS; 786 had_problem++; 787 /* 788 * If there a problem we should turn off the discard so we 789 * do not compromise the filesystem. 790 */ 791 ctx->options &= ~E2F_OPT_DISCARD; 792 793do_counts: 794 inodes++; 795 if (bitmap) { 796 if (ext2fs_test_inode_bitmap2(ctx->inode_dir_map, i)) 797 dirs_count++; 798 if (inodes > first_free) { 799 e2fsck_discard_inodes(ctx, group, first_free, 800 inodes - first_free); 801 first_free = fs->super->s_inodes_per_group + 1; 802 } 803 } else { 804 group_free++; 805 free_inodes++; 806 if (first_free > inodes) 807 first_free = inodes; 808 } 809 810 if ((inodes == fs->super->s_inodes_per_group) || 811 (i == fs->super->s_inodes_count)) { 812 /* 813 * If the last inode is free, we can discard it as well. 814 */ 815 if (!bitmap && inodes >= first_free) 816 e2fsck_discard_inodes(ctx, group, first_free, 817 inodes - first_free + 1); 818 /* 819 * If discard zeroes data and the group inode table 820 * was not zeroed yet, set itable as zeroed 821 */ 822 if ((ctx->options & E2F_OPT_DISCARD) && 823 io_channel_discard_zeroes_data(fs->io) && 824 !(ext2fs_bg_flags_test(fs, group, 825 EXT2_BG_INODE_ZEROED))) { 826 ext2fs_bg_flags_set(fs, group, 827 EXT2_BG_INODE_ZEROED); 828 ext2fs_group_desc_csum_set(fs, group); 829 } 830 831 first_free = fs->super->s_inodes_per_group + 1; 832 free_array[group] = group_free; 833 dir_array[group] = dirs_count; 834 group ++; 835 inodes = 0; 836 skip_group = 0; 837 group_free = 0; 838 dirs_count = 0; 839 if (ctx->progress) 840 if ((ctx->progress)(ctx, 5, 841 group + fs->group_desc_count, 842 fs->group_desc_count*2)) 843 goto errout; 844 if (csum_flag && 845 (i != fs->super->s_inodes_count) && 846 (ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT) 847 )) 848 skip_group++; 849 } 850 } 851 if (pctx.ino) 852 print_bitmap_problem(ctx, save_problem, &pctx); 853 854 if (had_problem) 855 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP); 856 else 857 fixit = -1; 858 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS; 859 860 if (fixit == 1) { 861 ext2fs_free_inode_bitmap(fs->inode_map); 862 retval = ext2fs_copy_bitmap(ctx->inode_used_map, 863 &fs->inode_map); 864 if (retval) { 865 clear_problem_context(&pctx); 866 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx); 867 ctx->flags |= E2F_FLAG_ABORT; 868 goto errout; 869 } 870 ext2fs_set_bitmap_padding(fs->inode_map); 871 ext2fs_mark_ib_dirty(fs); 872 873 /* redo counts */ 874 inodes = 0; free_inodes = 0; group_free = 0; 875 dirs_count = 0; group = 0; 876 memset(free_array, 0, fs->group_desc_count * sizeof(int)); 877 memset(dir_array, 0, fs->group_desc_count * sizeof(int)); 878 redo_flag++; 879 goto redo_counts; 880 } else if (fixit == 0) 881 ext2fs_unmark_valid(fs); 882 883 for (i = 0; i < fs->group_desc_count; i++) { 884 if (free_array[i] != ext2fs_bg_free_inodes_count(fs, i)) { 885 pctx.group = i; 886 pctx.ino = ext2fs_bg_free_inodes_count(fs, i); 887 pctx.ino2 = free_array[i]; 888 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP, 889 &pctx)) { 890 ext2fs_bg_free_inodes_count_set(fs, i, free_array[i]); 891 ext2fs_mark_super_dirty(fs); 892 } else 893 ext2fs_unmark_valid(fs); 894 } 895 if (dir_array[i] != ext2fs_bg_used_dirs_count(fs, i)) { 896 pctx.group = i; 897 pctx.ino = ext2fs_bg_used_dirs_count(fs, i); 898 pctx.ino2 = dir_array[i]; 899 900 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP, 901 &pctx)) { 902 ext2fs_bg_used_dirs_count_set(fs, i, dir_array[i]); 903 ext2fs_mark_super_dirty(fs); 904 } else 905 ext2fs_unmark_valid(fs); 906 } 907 } 908 if (free_inodes != fs->super->s_free_inodes_count) { 909 pctx.group = -1; 910 pctx.ino = fs->super->s_free_inodes_count; 911 pctx.ino2 = free_inodes; 912 913 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) { 914 fs->super->s_free_inodes_count = free_inodes; 915 ext2fs_mark_super_dirty(fs); 916 } 917 } 918errout: 919 ext2fs_free_mem(&free_array); 920 ext2fs_free_mem(&dir_array); 921} 922 923static void check_inode_end(e2fsck_t ctx) 924{ 925 ext2_filsys fs = ctx->fs; 926 ext2_ino_t end, save_inodes_count, i; 927 struct problem_context pctx; 928 929 clear_problem_context(&pctx); 930 931 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count; 932 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end, 933 &save_inodes_count); 934 if (pctx.errcode) { 935 pctx.num = 1; 936 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx); 937 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 938 return; 939 } 940 if (save_inodes_count == end) 941 return; 942 943 /* protect loop from wrap-around if end is maxed */ 944 for (i = save_inodes_count + 1; i <= end && i > save_inodes_count; i++) { 945 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) { 946 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) { 947 for (; i <= end; i++) 948 ext2fs_mark_inode_bitmap(fs->inode_map, 949 i); 950 ext2fs_mark_ib_dirty(fs); 951 } else 952 ext2fs_unmark_valid(fs); 953 break; 954 } 955 } 956 957 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, 958 save_inodes_count, 0); 959 if (pctx.errcode) { 960 pctx.num = 2; 961 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx); 962 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 963 return; 964 } 965} 966 967static void check_block_end(e2fsck_t ctx) 968{ 969 ext2_filsys fs = ctx->fs; 970 blk64_t end, save_blocks_count, i; 971 struct problem_context pctx; 972 973 clear_problem_context(&pctx); 974 975 end = ext2fs_get_block_bitmap_start2(fs->block_map) + 976 ((blk64_t)EXT2_CLUSTERS_PER_GROUP(fs->super) * fs->group_desc_count) - 1; 977 pctx.errcode = ext2fs_fudge_block_bitmap_end2(fs->block_map, end, 978 &save_blocks_count); 979 if (pctx.errcode) { 980 pctx.num = 3; 981 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx); 982 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 983 return; 984 } 985 if (save_blocks_count == end) 986 return; 987 988 /* Protect loop from wrap-around if end is maxed */ 989 for (i = save_blocks_count + 1; i <= end && i > save_blocks_count; i++) { 990 if (!ext2fs_test_block_bitmap2(fs->block_map, 991 EXT2FS_C2B(fs, i))) { 992 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) { 993 for (; i <= end; i++) 994 ext2fs_mark_block_bitmap2(fs->block_map, 995 EXT2FS_C2B(fs, i)); 996 ext2fs_mark_bb_dirty(fs); 997 } else 998 ext2fs_unmark_valid(fs); 999 break; 1000 } 1001 } 1002 1003 pctx.errcode = ext2fs_fudge_block_bitmap_end2(fs->block_map, 1004 save_blocks_count, 0); 1005 if (pctx.errcode) { 1006 pctx.num = 4; 1007 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx); 1008 ctx->flags |= E2F_FLAG_ABORT; /* fatal */ 1009 return; 1010 } 1011} 1012 1013 1014 1015