2 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
7 * This file may be redistributed under the terms of the GNU Public
15 #include <sys/types.h>
17 #include <sys/ioctl.h>
24 static void check_block_bitmaps(e2fsck_t ctx);
25 static void check_inode_bitmaps(e2fsck_t ctx);
26 static void check_inode_end(e2fsck_t ctx);
27 static void check_block_end(e2fsck_t ctx);
28 static void check_inode_bitmap_checksum(e2fsck_t ctx);
29 static void check_block_bitmap_checksum(e2fsck_t ctx);
31 void e2fsck_pass5(e2fsck_t ctx)
34 struct resource_track rtrack;
36 struct problem_context pctx;
39 mtrace_print("Pass 5");
42 init_resource_track(&rtrack, ctx->fs->io);
43 clear_problem_context(&pctx);
45 if (!(ctx->options & E2F_OPT_PREEN))
46 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
49 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
52 e2fsck_read_bitmaps(ctx);
54 check_block_bitmaps(ctx);
55 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
57 check_inode_bitmaps(ctx);
58 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
61 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
64 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
67 check_inode_bitmap_checksum(ctx);
68 check_block_bitmap_checksum(ctx);
70 ext2fs_free_inode_bitmap(ctx->inode_used_map);
71 ctx->inode_used_map = 0;
72 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
73 ctx->inode_dir_map = 0;
74 ext2fs_free_block_bitmap(ctx->block_found_map);
75 ctx->block_found_map = 0;
76 ext2fs_free_block_bitmap(ctx->block_metadata_map);
77 ctx->block_metadata_map = 0;
79 print_resource_track(ctx, _("Pass 5"), &rtrack, ctx->fs->io);
82 static void check_inode_bitmap_checksum(e2fsck_t ctx)
84 struct problem_context pctx;
91 if (!ext2fs_has_feature_metadata_csum(ctx->fs->super))
94 /* If bitmap is dirty from being fixed, checksum will be corrected */
95 if (ext2fs_test_ib_dirty(ctx->fs))
98 nbytes = (size_t)(EXT2_INODES_PER_GROUP(ctx->fs->super) / 8);
99 retval = ext2fs_get_mem(ctx->fs->blocksize, &buf);
101 com_err(ctx->program_name, 0, "%s",
102 _("check_inode_bitmap_checksum: Memory allocation error"));
106 clear_problem_context(&pctx);
107 for (i = 0; i < ctx->fs->group_desc_count; i++) {
108 if (ext2fs_bg_flags_test(ctx->fs, i, EXT2_BG_INODE_UNINIT))
111 ino_itr = 1 + (i * (nbytes << 3));
112 retval = ext2fs_get_inode_bitmap_range2(ctx->fs->inode_map,
113 ino_itr, nbytes << 3,
118 if (ext2fs_inode_bitmap_csum_verify(ctx->fs, i, buf, nbytes))
121 if (!fix_problem(ctx, PR_5_INODE_BITMAP_CSUM_INVALID, &pctx))
125 * Fixing one checksum will rewrite all of them. The bitmap
126 * will be checked against the one we made during pass1 for
127 * discrepancies, and fixed if need be.
129 ext2fs_mark_ib_dirty(ctx->fs);
133 ext2fs_free_mem(&buf);
136 static void check_block_bitmap_checksum(e2fsck_t ctx)
138 struct problem_context pctx;
145 if (!ext2fs_has_feature_metadata_csum(ctx->fs->super))
148 /* If bitmap is dirty from being fixed, checksum will be corrected */
149 if (ext2fs_test_bb_dirty(ctx->fs))
152 nbytes = (size_t)(EXT2_CLUSTERS_PER_GROUP(ctx->fs->super) / 8);
153 retval = ext2fs_get_mem(ctx->fs->blocksize, &buf);
155 com_err(ctx->program_name, 0, "%s",
156 _("check_block_bitmap_checksum: Memory allocation error"));
160 clear_problem_context(&pctx);
161 for (i = 0; i < ctx->fs->group_desc_count; i++) {
162 if (ext2fs_bg_flags_test(ctx->fs, i, EXT2_BG_BLOCK_UNINIT))
165 blk_itr = EXT2FS_B2C(ctx->fs,
166 ctx->fs->super->s_first_data_block) +
167 ((blk64_t) i * (nbytes << 3));
168 retval = ext2fs_get_block_bitmap_range2(ctx->fs->block_map,
169 blk_itr, nbytes << 3,
174 if (ext2fs_block_bitmap_csum_verify(ctx->fs, i, buf, nbytes))
177 if (!fix_problem(ctx, PR_5_BLOCK_BITMAP_CSUM_INVALID, &pctx))
181 * Fixing one checksum will rewrite all of them. The bitmap
182 * will be checked against the one we made during pass1 for
183 * discrepancies, and fixed if need be.
185 ext2fs_mark_bb_dirty(ctx->fs);
189 ext2fs_free_mem(&buf);
192 static void e2fsck_discard_blocks(e2fsck_t ctx, blk64_t start,
195 ext2_filsys fs = ctx->fs;
198 * If the filesystem has changed it means that there was an corruption
199 * which should be repaired, but in some cases just one e2fsck run is
200 * not enough to fix the problem, hence it is not safe to run discard
203 if (ext2fs_test_changed(fs))
204 ctx->options &= ~E2F_OPT_DISCARD;
206 if ((ctx->options & E2F_OPT_DISCARD) &&
207 (io_channel_discard(fs->io, start, count)))
208 ctx->options &= ~E2F_OPT_DISCARD;
212 * This will try to discard number 'count' inodes starting at
213 * inode number 'start' within the 'group'. Note that 'start'
214 * is 1-based, it means that we need to adjust it by -1 in this
215 * function to compute right offset in the particular inode table.
217 static void e2fsck_discard_inodes(e2fsck_t ctx, dgrp_t group,
218 ext2_ino_t start, int count)
220 ext2_filsys fs = ctx->fs;
224 * Sanity check for 'start'
226 if ((start < 1) || (start > EXT2_INODES_PER_GROUP(fs->super))) {
227 printf("PROGRAMMING ERROR: Got start %d outside of group %d!"
228 " Disabling discard\n",
230 ctx->options &= ~E2F_OPT_DISCARD;
234 * Do not attempt to discard if E2F_OPT_DISCARD is not set. And also
235 * skip the discard on this group if discard does not zero data.
236 * The reason is that if the inode table is not zeroed discard would
237 * no help us since we need to zero it anyway, or if the inode table
238 * is zeroed then the read after discard would not be deterministic
239 * anyway and we would not be able to assume that this inode table
240 * was zeroed anymore so we would have to zero it again, which does
241 * not really make sense.
243 if (!(ctx->options & E2F_OPT_DISCARD) ||
244 !io_channel_discard_zeroes_data(fs->io))
248 * Start is inode number within the group which starts
249 * counting from 1, so we need to adjust it.
254 * We can discard only blocks containing only unused
255 * inodes in the table.
257 blk = DIV_ROUND_UP(start,
258 EXT2_INODES_PER_BLOCK(fs->super));
259 count -= (blk * EXT2_INODES_PER_BLOCK(fs->super) - start);
260 blk += ext2fs_inode_table_loc(fs, group);
261 num = count / EXT2_INODES_PER_BLOCK(fs->super);
264 e2fsck_discard_blocks(ctx, blk, num);
267 #define NO_BLK ((blk64_t) -1)
269 static void print_bitmap_problem(e2fsck_t ctx, problem_t problem,
270 struct problem_context *pctx)
273 case PR_5_BLOCK_UNUSED:
274 if (pctx->blk == pctx->blk2)
277 problem = PR_5_BLOCK_RANGE_UNUSED;
279 case PR_5_BLOCK_USED:
280 if (pctx->blk == pctx->blk2)
283 problem = PR_5_BLOCK_RANGE_USED;
285 case PR_5_INODE_UNUSED:
286 if (pctx->ino == pctx->ino2)
289 problem = PR_5_INODE_RANGE_UNUSED;
291 case PR_5_INODE_USED:
292 if (pctx->ino == pctx->ino2)
295 problem = PR_5_INODE_RANGE_USED;
298 fix_problem(ctx, problem, pctx);
299 pctx->blk = pctx->blk2 = NO_BLK;
300 pctx->ino = pctx->ino2 = 0;
303 /* Just to be more succinct */
304 #define B2C(x) EXT2FS_B2C(fs, (x))
305 #define EQ_CLSTR(x, y) (B2C(x) == B2C(y))
306 #define LE_CLSTR(x, y) (B2C(x) <= B2C(y))
307 #define GE_CLSTR(x, y) (B2C(x) >= B2C(y))
309 static void check_block_bitmaps(e2fsck_t ctx)
311 ext2_filsys fs = ctx->fs;
313 unsigned int *free_array;
315 unsigned int blocks = 0;
316 blk64_t free_blocks = 0;
317 blk64_t first_free = ext2fs_blocks_count(fs->super);
318 unsigned int group_free = 0;
320 struct problem_context pctx;
321 problem_t problem, save_problem;
322 int fixit, had_problem;
325 char *actual_buf, *bitmap_buf;
327 actual_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize,
328 "actual bitmap buffer");
329 bitmap_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize,
330 "bitmap block buffer");
332 clear_problem_context(&pctx);
333 free_array = (unsigned int *) e2fsck_allocate_memory(ctx,
334 fs->group_desc_count * sizeof(unsigned int), "free block count array");
336 if ((B2C(fs->super->s_first_data_block) <
337 ext2fs_get_block_bitmap_start2(ctx->block_found_map)) ||
338 (B2C(ext2fs_blocks_count(fs->super)-1) >
339 ext2fs_get_block_bitmap_end2(ctx->block_found_map))) {
341 pctx.blk = B2C(fs->super->s_first_data_block);
342 pctx.blk2 = B2C(ext2fs_blocks_count(fs->super) - 1);
343 pctx.ino = ext2fs_get_block_bitmap_start2(ctx->block_found_map);
344 pctx.ino2 = ext2fs_get_block_bitmap_end2(ctx->block_found_map);
345 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
347 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
351 if ((B2C(fs->super->s_first_data_block) <
352 ext2fs_get_block_bitmap_start2(fs->block_map)) ||
353 (B2C(ext2fs_blocks_count(fs->super)-1) >
354 ext2fs_get_block_bitmap_end2(fs->block_map))) {
356 pctx.blk = B2C(fs->super->s_first_data_block);
357 pctx.blk2 = B2C(ext2fs_blocks_count(fs->super) - 1);
358 pctx.ino = ext2fs_get_block_bitmap_start2(fs->block_map);
359 pctx.ino2 = ext2fs_get_block_bitmap_end2(fs->block_map);
360 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
362 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
369 pctx.blk = pctx.blk2 = NO_BLK;
370 for (i = B2C(fs->super->s_first_data_block);
371 i < ext2fs_blocks_count(fs->super);
372 i += EXT2FS_CLUSTER_RATIO(fs)) {
373 int first_block_in_bg = (B2C(i) -
374 B2C(fs->super->s_first_data_block)) %
375 fs->super->s_clusters_per_group == 0;
376 int n, nbytes = fs->super->s_clusters_per_group / 8;
378 actual = ext2fs_fast_test_block_bitmap2(ctx->block_found_map, i);
381 * Try to optimize pass5 by extracting a bitmap block
382 * as expected from what we have on disk, and then
383 * comparing the two. If they are identical, then
384 * update the free block counts and go on to the next
385 * block group. This is much faster than doing the
386 * individual bit-by-bit comparison. The one downside
387 * is that this doesn't work if we are asking e2fsck
388 * to do a discard operation.
390 if (!first_block_in_bg ||
391 (group == fs->group_desc_count - 1) ||
392 (ctx->options & E2F_OPT_DISCARD))
395 retval = ext2fs_get_block_bitmap_range2(ctx->block_found_map,
396 B2C(i), fs->super->s_clusters_per_group,
400 retval = ext2fs_get_block_bitmap_range2(fs->block_map,
401 B2C(i), fs->super->s_clusters_per_group,
405 if (memcmp(actual_buf, bitmap_buf, nbytes) != 0)
407 n = ext2fs_bitcount(actual_buf, nbytes);
408 group_free = fs->super->s_clusters_per_group - n;
409 free_blocks += group_free;
410 i += EXT2FS_C2B(fs, fs->super->s_clusters_per_group - 1);
417 bitmap = ext2fs_fast_test_block_bitmap2(fs->block_map, i);
419 if (!actual == !bitmap)
422 if (!actual && bitmap) {
424 * Block not used, but marked in use in the bitmap.
426 problem = PR_5_BLOCK_UNUSED;
429 * Block used, but not marked in use in the bitmap.
431 problem = PR_5_BLOCK_USED;
433 if (ext2fs_bg_flags_test(fs, group,
434 EXT2_BG_BLOCK_UNINIT)) {
435 struct problem_context pctx2;
438 if (fix_problem(ctx, PR_5_BLOCK_UNINIT,
440 ext2fs_bg_flags_clear(fs, group,
441 EXT2_BG_BLOCK_UNINIT);
444 if (pctx.blk == NO_BLK) {
445 pctx.blk = pctx.blk2 = i;
446 save_problem = problem;
448 if ((problem == save_problem) &&
449 (pctx.blk2 == i - EXT2FS_CLUSTER_RATIO(fs)))
450 pctx.blk2 += EXT2FS_CLUSTER_RATIO(fs);
452 print_bitmap_problem(ctx, save_problem, &pctx);
453 pctx.blk = pctx.blk2 = i;
454 save_problem = problem;
457 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
461 * If there a problem we should turn off the discard so we
462 * do not compromise the filesystem.
464 ctx->options &= ~E2F_OPT_DISCARD;
472 } else if (i > first_free) {
473 e2fsck_discard_blocks(ctx, first_free,
475 first_free = ext2fs_blocks_count(fs->super);
478 if ((blocks == fs->super->s_clusters_per_group) ||
479 (EXT2FS_B2C(fs, i) ==
480 EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super)-1))) {
482 * If the last block of this group is free, then we can
483 * discard it as well.
485 if (!bitmap && i >= first_free)
486 e2fsck_discard_blocks(ctx, first_free,
487 (i - first_free) + 1);
489 first_free = ext2fs_blocks_count(fs->super);
491 free_array[group] = group_free;
496 if ((ctx->progress)(ctx, 5, group,
497 fs->group_desc_count*2))
501 if (pctx.blk != NO_BLK)
502 print_bitmap_problem(ctx, save_problem, &pctx);
504 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
507 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
510 ext2fs_free_block_bitmap(fs->block_map);
511 retval = ext2fs_copy_bitmap(ctx->block_found_map,
514 clear_problem_context(&pctx);
515 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
516 ctx->flags |= E2F_FLAG_ABORT;
519 ext2fs_set_bitmap_padding(fs->block_map);
520 ext2fs_mark_bb_dirty(fs);
522 /* Redo the counts */
523 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
524 memset(free_array, 0, fs->group_desc_count * sizeof(int));
527 } else if (fixit == 0)
528 ext2fs_unmark_valid(fs);
530 for (g = 0; g < fs->group_desc_count; g++) {
531 if (free_array[g] != ext2fs_bg_free_blocks_count(fs, g)) {
533 pctx.blk = ext2fs_bg_free_blocks_count(fs, g);
534 pctx.blk2 = free_array[g];
536 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
538 ext2fs_bg_free_blocks_count_set(fs, g, free_array[g]);
539 ext2fs_mark_super_dirty(fs);
541 ext2fs_unmark_valid(fs);
544 free_blocks = EXT2FS_C2B(fs, free_blocks);
545 if (free_blocks != ext2fs_free_blocks_count(fs->super)) {
547 pctx.blk = ext2fs_free_blocks_count(fs->super);
548 pctx.blk2 = free_blocks;
550 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
551 ext2fs_free_blocks_count_set(fs->super, free_blocks);
552 ext2fs_mark_super_dirty(fs);
556 ext2fs_free_mem(&free_array);
557 ext2fs_free_mem(&actual_buf);
558 ext2fs_free_mem(&bitmap_buf);
561 static void check_inode_bitmaps(e2fsck_t ctx)
563 ext2_filsys fs = ctx->fs;
565 unsigned int free_inodes = 0;
569 unsigned int inodes = 0;
570 ext2_ino_t *free_array;
571 ext2_ino_t *dir_array;
574 struct problem_context pctx;
575 problem_t problem, save_problem;
576 int fixit, had_problem;
580 ext2_ino_t first_free = fs->super->s_inodes_per_group + 1;
582 clear_problem_context(&pctx);
583 free_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
584 fs->group_desc_count * sizeof(ext2_ino_t), "free inode count array");
586 dir_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
587 fs->group_desc_count * sizeof(ext2_ino_t), "directory count array");
589 if ((1 < ext2fs_get_inode_bitmap_start2(ctx->inode_used_map)) ||
590 (fs->super->s_inodes_count >
591 ext2fs_get_inode_bitmap_end2(ctx->inode_used_map))) {
594 pctx.blk2 = fs->super->s_inodes_count;
595 pctx.ino = ext2fs_get_inode_bitmap_start2(ctx->inode_used_map);
596 pctx.ino2 = ext2fs_get_inode_bitmap_end2(ctx->inode_used_map);
597 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
599 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
602 if ((1 < ext2fs_get_inode_bitmap_start2(fs->inode_map)) ||
603 (fs->super->s_inodes_count >
604 ext2fs_get_inode_bitmap_end2(fs->inode_map))) {
607 pctx.blk2 = fs->super->s_inodes_count;
608 pctx.ino = ext2fs_get_inode_bitmap_start2(fs->inode_map);
609 pctx.ino2 = ext2fs_get_inode_bitmap_end2(fs->inode_map);
610 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
612 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
616 csum_flag = ext2fs_has_group_desc_csum(fs);
620 pctx.ino = pctx.ino2 = 0;
622 (ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT)))
625 /* Protect loop from wrap-around if inodes_count is maxed */
626 for (i = 1; i <= fs->super->s_inodes_count && i > 0; i++) {
629 i % fs->super->s_inodes_per_group == 1) {
631 * Current inode is the first inode
632 * in the current block group.
634 if (ext2fs_test_inode_bitmap_range(
635 ctx->inode_used_map, i,
636 fs->super->s_inodes_per_group)) {
638 * When the compared inodes in inodes bitmap
639 * are 0, count the free inode,
640 * skip the current block group.
643 inodes = fs->super->s_inodes_per_group - 1;
645 free_inodes += inodes;
652 actual = ext2fs_fast_test_inode_bitmap2(ctx->inode_used_map, i);
655 else if (!skip_group)
656 bitmap = ext2fs_fast_test_inode_bitmap2(fs->inode_map, i);
657 if (!actual == !bitmap)
660 if (!actual && bitmap) {
662 * Inode wasn't used, but marked in bitmap
664 problem = PR_5_INODE_UNUSED;
665 } else /* if (actual && !bitmap) */ {
667 * Inode used, but not in bitmap
669 problem = PR_5_INODE_USED;
671 /* We should never hit this, because it means that
672 * inodes were marked in use that weren't noticed
673 * in pass1 or pass 2. It is easier to fix the problem
674 * than to kill e2fsck and leave the user stuck. */
676 struct problem_context pctx2;
679 if (fix_problem(ctx, PR_5_INODE_UNINIT,&pctx2)){
680 ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT);
686 pctx.ino = pctx.ino2 = i;
687 save_problem = problem;
689 if ((problem == save_problem) &&
693 print_bitmap_problem(ctx, save_problem, &pctx);
694 pctx.ino = pctx.ino2 = i;
695 save_problem = problem;
698 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
701 * If there a problem we should turn off the discard so we
702 * do not compromise the filesystem.
704 ctx->options &= ~E2F_OPT_DISCARD;
709 if (ext2fs_test_inode_bitmap2(ctx->inode_dir_map, i))
711 if (inodes > first_free) {
712 e2fsck_discard_inodes(ctx, group, first_free,
713 inodes - first_free);
714 first_free = fs->super->s_inodes_per_group + 1;
719 if (first_free > inodes)
723 if ((inodes == fs->super->s_inodes_per_group) ||
724 (i == fs->super->s_inodes_count)) {
726 * If the last inode is free, we can discard it as well.
728 if (!bitmap && inodes >= first_free)
729 e2fsck_discard_inodes(ctx, group, first_free,
730 inodes - first_free + 1);
732 * If discard zeroes data and the group inode table
733 * was not zeroed yet, set itable as zeroed
735 if ((ctx->options & E2F_OPT_DISCARD) &&
736 io_channel_discard_zeroes_data(fs->io) &&
737 !(ext2fs_bg_flags_test(fs, group,
738 EXT2_BG_INODE_ZEROED))) {
739 ext2fs_bg_flags_set(fs, group,
740 EXT2_BG_INODE_ZEROED);
741 ext2fs_group_desc_csum_set(fs, group);
744 first_free = fs->super->s_inodes_per_group + 1;
745 free_array[group] = group_free;
746 dir_array[group] = dirs_count;
753 if ((ctx->progress)(ctx, 5,
754 group + fs->group_desc_count,
755 fs->group_desc_count*2))
758 (i != fs->super->s_inodes_count) &&
759 (ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT)
765 print_bitmap_problem(ctx, save_problem, &pctx);
768 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
771 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
774 ext2fs_free_inode_bitmap(fs->inode_map);
775 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
778 clear_problem_context(&pctx);
779 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
780 ctx->flags |= E2F_FLAG_ABORT;
783 ext2fs_set_bitmap_padding(fs->inode_map);
784 ext2fs_mark_ib_dirty(fs);
787 inodes = 0; free_inodes = 0; group_free = 0;
788 dirs_count = 0; group = 0;
789 memset(free_array, 0, fs->group_desc_count * sizeof(int));
790 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
793 } else if (fixit == 0)
794 ext2fs_unmark_valid(fs);
796 for (i = 0; i < fs->group_desc_count; i++) {
797 if (free_array[i] != ext2fs_bg_free_inodes_count(fs, i)) {
799 pctx.ino = ext2fs_bg_free_inodes_count(fs, i);
800 pctx.ino2 = free_array[i];
801 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
803 ext2fs_bg_free_inodes_count_set(fs, i, free_array[i]);
804 ext2fs_mark_super_dirty(fs);
806 ext2fs_unmark_valid(fs);
808 if (dir_array[i] != ext2fs_bg_used_dirs_count(fs, i)) {
810 pctx.ino = ext2fs_bg_used_dirs_count(fs, i);
811 pctx.ino2 = dir_array[i];
813 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
815 ext2fs_bg_used_dirs_count_set(fs, i, dir_array[i]);
816 ext2fs_mark_super_dirty(fs);
818 ext2fs_unmark_valid(fs);
821 if (free_inodes != fs->super->s_free_inodes_count) {
823 pctx.ino = fs->super->s_free_inodes_count;
824 pctx.ino2 = free_inodes;
826 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
827 fs->super->s_free_inodes_count = free_inodes;
828 ext2fs_mark_super_dirty(fs);
832 ext2fs_free_mem(&free_array);
833 ext2fs_free_mem(&dir_array);
836 static void check_inode_end(e2fsck_t ctx)
838 ext2_filsys fs = ctx->fs;
839 ext2_ino_t end, save_inodes_count, i;
840 struct problem_context pctx;
843 clear_problem_context(&pctx);
845 end = (__u64)EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
846 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
850 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
851 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
854 if (save_inodes_count == end)
855 goto check_intra_bg_tail;
857 /* protect loop from wrap-around if end is maxed */
858 for (i = save_inodes_count + 1; i <= end && i > save_inodes_count; i++) {
859 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,
865 ext2fs_mark_ib_dirty(fs);
867 ext2fs_unmark_valid(fs);
872 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
873 save_inodes_count, 0);
876 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
877 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
881 * If the number of inodes per block group != blocksize, we
882 * can also have a potential problem with the tail bits in
883 * each individual inode bitmap block. If there is a problem,
884 * it would have been noticed when the bitmap was loaded. And
885 * fixing this is easy; all we need to do force the bitmap to
886 * be written back to disk.
889 if (!asked && fs->flags & EXT2_FLAG_IBITMAP_TAIL_PROBLEM) {
890 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx))
891 ext2fs_mark_ib_dirty(fs);
893 ext2fs_unmark_valid(fs);
897 static void check_block_end(e2fsck_t ctx)
899 ext2_filsys fs = ctx->fs;
900 blk64_t end, save_blocks_count, i;
901 struct problem_context pctx;
904 clear_problem_context(&pctx);
906 end = ext2fs_get_block_bitmap_start2(fs->block_map) +
907 EXT2_GROUPS_TO_CLUSTERS(fs->super, fs->group_desc_count) - 1;
908 pctx.errcode = ext2fs_fudge_block_bitmap_end2(fs->block_map, end,
912 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
913 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
916 if (save_blocks_count == end)
917 goto check_intra_bg_tail;
919 /* Protect loop from wrap-around if end is maxed */
920 for (i = save_blocks_count + 1; i <= end && i > save_blocks_count; i++) {
921 if (!ext2fs_test_block_bitmap2(fs->block_map,
922 EXT2FS_C2B(fs, i))) {
924 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
925 for (; i <= end; i++)
926 ext2fs_mark_block_bitmap2(fs->block_map,
928 ext2fs_mark_bb_dirty(fs);
930 ext2fs_unmark_valid(fs);
935 pctx.errcode = ext2fs_fudge_block_bitmap_end2(fs->block_map,
936 save_blocks_count, 0);
939 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
940 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
944 * If the number of blocks per block group != blocksize, we
945 * can also have a potential problem with the tail bits in
946 * each individual block bitmap block. If there is a problem,
947 * it would have been noticed when the bitmap was loaded. And
948 * fixing this is easy; all we need to do force the bitmap to
949 * be written back to disk.
952 if (!asked && fs->flags & EXT2_FLAG_BBITMAP_TAIL_PROBLEM) {
953 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx))
954 ext2fs_mark_bb_dirty(fs);
956 ext2fs_unmark_valid(fs);