Whamcloud - gitweb
tests: use make rules to run tests in parallel
[tools/e2fsprogs.git] / e2fsck / pass5.c
index e25f080..8312fe0 100644 (file)
@@ -88,8 +88,7 @@ static void e2fsck_discard_blocks(e2fsck_t ctx, blk64_t start,
        if (ext2fs_test_changed(fs))
                ctx->options &= ~E2F_OPT_DISCARD;
 
-       if (!(ctx->options & E2F_OPT_NO) &&
-           (ctx->options & E2F_OPT_DISCARD) &&
+       if ((ctx->options & E2F_OPT_DISCARD) &&
            (io_channel_discard(fs->io, start, count)))
                ctx->options &= ~E2F_OPT_DISCARD;
 }
@@ -100,12 +99,11 @@ static void e2fsck_discard_blocks(e2fsck_t ctx, blk64_t start,
  * is 1-based, it means that we need to adjust it by -1 in this
  * function to compute right offset in the particular inode table.
  */
-static void e2fsck_discard_inodes(e2fsck_t ctx, int group,
-                                 int start, int count)
+static void e2fsck_discard_inodes(e2fsck_t ctx, dgrp_t group,
+                                 ext2_ino_t start, int count)
 {
        ext2_filsys fs = ctx->fs;
        blk64_t blk, num;
-       int orig = count;
 
        /*
         * Sanity check for 'start'
@@ -117,7 +115,18 @@ static void e2fsck_discard_inodes(e2fsck_t ctx, int group,
                ctx->options &= ~E2F_OPT_DISCARD;
        }
 
-       if ((ctx->options & E2F_OPT_NO) || !(ctx->options & E2F_OPT_DISCARD))
+       /*
+        * Do not attempt to discard if E2F_OPT_DISCARD is not set. And also
+        * skip the discard on this group if discard does not zero data.
+        * The reason is that if the inode table is not zeroed discard would
+        * no help us since we need to zero it anyway, or if the inode table
+        * is zeroed then the read after discard would not be deterministic
+        * anyway and we would not be able to assume that this inode table
+        * was zeroed anymore so we would have to zero it again, which does
+        * not really make sense.
+        */
+       if (!(ctx->options & E2F_OPT_DISCARD) ||
+           !io_channel_discard_zeroes_data(fs->io))
                return;
 
        /*
@@ -186,12 +195,12 @@ static void check_block_bitmaps(e2fsck_t ctx)
 {
        ext2_filsys fs = ctx->fs;
        blk64_t i;
-       int     *free_array;
+       unsigned int    *free_array;
        int     group = 0;
-       int     blocks = 0;
+       unsigned int    blocks = 0;
        blk64_t free_blocks = 0;
        blk64_t first_free = ext2fs_blocks_count(fs->super);
-       int     group_free = 0;
+       unsigned int    group_free = 0;
        int     actual, bitmap;
        struct problem_context  pctx;
        int     problem, save_problem, fixit, had_problem;
@@ -203,11 +212,10 @@ static void check_block_bitmaps(e2fsck_t ctx)
        int     cmp_block = 0;
        int     redo_flag = 0;
        blk64_t super_blk, old_desc_blk, new_desc_blk;
-       io_manager      manager = ctx->fs->io->manager;
 
        clear_problem_context(&pctx);
-       free_array = (int *) e2fsck_allocate_memory(ctx,
-           fs->group_desc_count * sizeof(int), "free block count array");
+       free_array = (unsigned int *) e2fsck_allocate_memory(ctx,
+           fs->group_desc_count * sizeof(unsigned int), "free block count array");
 
        if ((B2C(fs->super->s_first_data_block) <
             ext2fs_get_block_bitmap_start2(ctx->block_found_map)) ||
@@ -372,15 +380,14 @@ redo_counts:
                ctx->options &= ~E2F_OPT_DISCARD;
 
        do_counts:
-               if (!bitmap && (!skip_group || csum_flag)) {
+               if (!bitmap) {
                        group_free++;
                        free_blocks++;
                        if (first_free > i)
                                first_free = i;
-               } else {
-                       if (i > first_free)
-                               e2fsck_discard_blocks(ctx, first_free,
-                                                     (i - first_free));
+               } else if (i > first_free) {
+                       e2fsck_discard_blocks(ctx, first_free,
+                                             (i - first_free));
                        first_free = ext2fs_blocks_count(fs->super);
                }
                blocks ++;
@@ -464,8 +471,7 @@ redo_counts:
                if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
                        ext2fs_free_blocks_count_set(fs->super, free_blocks);
                        ext2fs_mark_super_dirty(fs);
-               } else
-                       ext2fs_unmark_valid(fs);
+               }
        }
 errout:
        ext2fs_free_mem(&free_array);
@@ -480,8 +486,8 @@ static void check_inode_bitmaps(e2fsck_t ctx)
        int             dirs_count = 0;
        int             group = 0;
        unsigned int    inodes = 0;
-       int             *free_array;
-       int             *dir_array;
+       ext2_ino_t      *free_array;
+       ext2_ino_t      *dir_array;
        int             actual, bitmap;
        errcode_t       retval;
        struct problem_context  pctx;
@@ -489,15 +495,14 @@ static void check_inode_bitmaps(e2fsck_t ctx)
        int             csum_flag;
        int             skip_group = 0;
        int             redo_flag = 0;
-       io_manager      manager = ctx->fs->io->manager;
-       int             first_free = fs->super->s_inodes_per_group + 1;
+       ext2_ino_t              first_free = fs->super->s_inodes_per_group + 1;
 
        clear_problem_context(&pctx);
-       free_array = (int *) e2fsck_allocate_memory(ctx,
-           fs->group_desc_count * sizeof(int), "free inode count array");
+       free_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
+           fs->group_desc_count * sizeof(ext2_ino_t), "free inode count array");
 
-       dir_array = (int *) e2fsck_allocate_memory(ctx,
-          fs->group_desc_count * sizeof(int), "directory count array");
+       dir_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
+          fs->group_desc_count * sizeof(ext2_ino_t), "directory count array");
 
        if ((1 < ext2fs_get_inode_bitmap_start2(ctx->inode_used_map)) ||
            (fs->super->s_inodes_count >
@@ -627,7 +632,7 @@ do_counts:
                                                      inodes - first_free);
                                first_free = fs->super->s_inodes_per_group + 1;
                        }
-               } else if (!skip_group || csum_flag) {
+               } else {
                        group_free++;
                        free_inodes++;
                        if (first_free > inodes)
@@ -740,8 +745,7 @@ do_counts:
                if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
                        fs->super->s_free_inodes_count = free_inodes;
                        ext2fs_mark_super_dirty(fs);
-               } else
-                       ext2fs_unmark_valid(fs);
+               }
        }
 errout:
        ext2fs_free_mem(&free_array);