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