X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=e2fsck%2Fpass5.c;h=e708fa41d41d0072ef16e1001bef944dec9afe29;hb=95a8d1de512f7ae55b78d99db21bb0d5973d115e;hp=274052ece2138bb1970a0647a3a0f80bc72b90cb;hpb=e79d1b23edd7ce551030128bfe12821f4412cc89;p=tools%2Fe2fsprogs.git diff --git a/e2fsck/pass5.c b/e2fsck/pass5.c index 274052e..e708fa4 100644 --- a/e2fsck/pass5.c +++ b/e2fsck/pass5.c @@ -65,23 +65,61 @@ void e2fsck_pass5(e2fsck_t ctx) ctx->block_found_map = 0; #ifdef RESOURCE_TRACK - if (ctx->options & E2F_OPT_TIME2) - print_resource_track("Pass 5", &rtrack); + if (ctx->options & E2F_OPT_TIME2) { + e2fsck_clear_progbar(ctx); + print_resource_track(_("Pass 5"), &rtrack); + } #endif } +#define NO_BLK ((blk_t) -1) + +static void print_bitmap_problem(e2fsck_t ctx, int problem, + struct problem_context *pctx) +{ + switch (problem) { + case PR_5_BLOCK_UNUSED: + if (pctx->blk == pctx->blk2) + pctx->blk2 = 0; + else + problem = PR_5_BLOCK_RANGE_UNUSED; + break; + case PR_5_BLOCK_USED: + if (pctx->blk == pctx->blk2) + pctx->blk2 = 0; + else + problem = PR_5_BLOCK_RANGE_USED; + break; + case PR_5_INODE_UNUSED: + if (pctx->ino == pctx->ino2) + pctx->ino2 = 0; + else + problem = PR_5_INODE_RANGE_UNUSED; + break; + case PR_5_INODE_USED: + if (pctx->ino == pctx->ino2) + pctx->ino2 = 0; + else + problem = PR_5_INODE_RANGE_USED; + break; + } + fix_problem(ctx, problem, pctx); + pctx->blk = pctx->blk2 = NO_BLK; + pctx->ino = pctx->ino2 = 0; +} + static void check_block_bitmaps(e2fsck_t ctx) { ext2_filsys fs = ctx->fs; blk_t i; int *free_array; int group = 0; - int blocks = 0; - int free_blocks = 0; + unsigned int blocks = 0; + unsigned int free_blocks = 0; int group_free = 0; int actual, bitmap; struct problem_context pctx; - int problem, fixit, had_problem; + int problem, save_problem, fixit, had_problem; errcode_t retval; clear_problem_context(&pctx); @@ -120,6 +158,8 @@ static void check_block_bitmaps(e2fsck_t ctx) redo_counts: had_problem = 0; + save_problem = 0; + pctx.blk = pctx.blk2 = NO_BLK; for (i = fs->super->s_first_data_block; i < fs->super->s_blocks_count; i++) { @@ -133,15 +173,27 @@ redo_counts: /* * Block not used, but marked in use in the bitmap. */ - problem = PR_5_UNUSED_BLOCK; + problem = PR_5_BLOCK_UNUSED; } else { /* * Block used, but not marked in use in the bitmap. */ problem = PR_5_BLOCK_USED; } - pctx.blk = i; - fix_problem(ctx, problem, &pctx); + if (pctx.blk == NO_BLK) { + pctx.blk = pctx.blk2 = i; + save_problem = problem; + } else { + if ((problem == save_problem) && + (pctx.blk2 == i-1)) + pctx.blk2++; + else { + print_bitmap_problem(ctx, save_problem, &pctx); + pctx.blk = pctx.blk2 = i; + save_problem = problem; + } + } + ctx->flags |= E2F_FLAG_PROG_SUPPRESS; had_problem++; do_counts: @@ -162,15 +214,24 @@ redo_counts: return; } } + if (pctx.blk != NO_BLK) + print_bitmap_problem(ctx, save_problem, &pctx); if (had_problem) - fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP); + fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP); else fixit = -1; + ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS; + if (fixit == 1) { ext2fs_free_block_bitmap(fs->block_map); retval = ext2fs_copy_bitmap(ctx->block_found_map, &fs->block_map); - /* XXX check retval --- should never fail! */ + if (retval) { + clear_problem_context(&pctx); + fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx); + ctx->flags |= E2F_FLAG_ABORT; + return; + } ext2fs_set_bitmap_padding(fs->block_map); ext2fs_mark_bb_dirty(fs); @@ -207,24 +268,24 @@ redo_counts: } else ext2fs_unmark_valid(fs); } - ext2fs_free_mem((void **) &free_array); + ext2fs_free_mem(&free_array); } static void check_inode_bitmaps(e2fsck_t ctx) { ext2_filsys fs = ctx->fs; - ino_t i; - int free_inodes = 0; - int group_free = 0; - int dirs_count = 0; - int group = 0; - int inodes = 0; - int *free_array; - int *dir_array; - int actual, bitmap; + ext2_ino_t i; + unsigned int free_inodes = 0; + int group_free = 0; + int dirs_count = 0; + int group = 0; + unsigned int inodes = 0; + int *free_array; + int *dir_array; + int actual, bitmap; errcode_t retval; struct problem_context pctx; - int problem, fixit, had_problem; + int problem, save_problem, fixit, had_problem; clear_problem_context(&pctx); free_array = (int *) e2fsck_allocate_memory(ctx, @@ -262,6 +323,8 @@ static void check_inode_bitmaps(e2fsck_t ctx) redo_counts: had_problem = 0; + save_problem = 0; + pctx.ino = pctx.ino2 = 0; for (i = 1; i <= fs->super->s_inodes_count; i++) { actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i); bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i); @@ -273,15 +336,27 @@ redo_counts: /* * Inode wasn't used, but marked in bitmap */ - problem = PR_5_UNUSED_INODE; + problem = PR_5_INODE_UNUSED; } else /* if (actual && !bitmap) */ { /* * Inode used, but not in bitmap */ problem = PR_5_INODE_USED; } - pctx.ino = i; - fix_problem(ctx, problem, &pctx); + if (pctx.ino == 0) { + pctx.ino = pctx.ino2 = i; + save_problem = problem; + } else { + if ((problem == save_problem) && + (pctx.ino2 == i-1)) + pctx.ino2++; + else { + print_bitmap_problem(ctx, save_problem, &pctx); + pctx.ino = pctx.ino2 = i; + save_problem = problem; + } + } + ctx->flags |= E2F_FLAG_PROG_SUPPRESS; had_problem++; do_counts: @@ -308,15 +383,25 @@ do_counts: return; } } + if (pctx.ino) + print_bitmap_problem(ctx, save_problem, &pctx); + if (had_problem) fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP); else fixit = -1; + ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS; + if (fixit == 1) { ext2fs_free_inode_bitmap(fs->inode_map); retval = ext2fs_copy_bitmap(ctx->inode_used_map, &fs->inode_map); - /* XXX check retval --- should never fail! */ + if (retval) { + clear_problem_context(&pctx); + fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx); + ctx->flags |= E2F_FLAG_ABORT; + return; + } ext2fs_set_bitmap_padding(fs->inode_map); ext2fs_mark_ib_dirty(fs); @@ -367,14 +452,14 @@ do_counts: } else ext2fs_unmark_valid(fs); } - ext2fs_free_mem((void **) &free_array); - ext2fs_free_mem((void **) &dir_array); + ext2fs_free_mem(&free_array); + ext2fs_free_mem(&dir_array); } static void check_inode_end(e2fsck_t ctx) { ext2_filsys fs = ctx->fs; - ino_t end, save_inodes_count, i; + ext2_ino_t end, save_inodes_count, i; struct problem_context pctx; clear_problem_context(&pctx);