resize2fs: fix minimum required blocks for flex_bg file systems
authorTaeyoung Kim <ty317.kim@samsung.com>
Fri, 4 Dec 2015 08:27:05 +0000 (17:27 +0900)
committerwchang kim <wchang.kim@samsung.com>
Tue, 20 Jun 2017 08:30:21 +0000 (17:30 +0900)
- This patch makes the image size lesser

Change-Id: Iadc3ece593e0418c651e6c9d20d4aed160550787
Signed-off-by: Taeyoung Kim <ty317.kim@samsung.com>
resize/resize2fs.c
tests/scripts/resize_test

index 8f6d95e..0dd7838 100644 (file)
@@ -2788,11 +2788,12 @@ static int calc_group_overhead(ext2_filsys fs, blk64_t grp,
 blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
 {
        ext2_ino_t inode_count;
-       dgrp_t groups, flex_groups;
+       dgrp_t groups;
        blk64_t blks_needed, data_blocks;
        blk64_t grp, data_needed, last_start;
        blk64_t overhead = 0;
        int old_desc_blocks;
+       int extra_groups = 0;
        int flexbg_size = 1 << fs->super->s_log_groups_per_flex;
 
        /*
@@ -2837,13 +2838,11 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
         * inode tables of slack space so the resize operation can be
         * guaranteed to finish.
         */
-       flex_groups = groups;
-       if (ext2fs_has_feature_flex_bg(fs->super)) {
-               dgrp_t remainder = groups & (flexbg_size - 1);
-
-               flex_groups += flexbg_size - remainder;
-               if (flex_groups > fs->group_desc_count)
-                       flex_groups = fs->group_desc_count;
+       blks_needed = data_needed;
+       if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) {
+               extra_groups = flexbg_size - (groups & (flexbg_size - 1));
+               blks_needed += fs->inode_blocks_per_group * extra_groups;
+               extra_groups = groups % flexbg_size;
        }
 
        /*
@@ -2852,7 +2851,7 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
         */
        data_blocks = EXT2_GROUPS_TO_BLOCKS(fs->super, groups);
        last_start = 0;
-       for (grp = 0; grp < flex_groups; grp++) {
+       for (grp = 0; grp < groups; grp++) {
                overhead = calc_group_overhead(fs, grp, old_desc_blocks);
 
                /*
@@ -2860,14 +2859,11 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
                 * the groups leading up to the last group so we can determine
                 * how big the last group needs to be
                 */
-               if (grp < (groups - 1))
+               if (grp != (groups - 1))
                        last_start += EXT2_BLOCKS_PER_GROUP(fs->super) -
                                overhead;
 
-               if (data_blocks > overhead)
-                       data_blocks -= overhead;
-               else
-                       data_blocks = 0;
+               data_blocks -= overhead;
        }
 #ifdef RESIZE2FS_DEBUG
        if (flags & RESIZE_DEBUG_MIN_CALC)
@@ -2879,7 +2875,6 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
         * if we need more group descriptors in order to accomodate our data
         * then we need to add them here
         */
-       blks_needed = data_needed;
        while (blks_needed > data_blocks) {
                blk64_t remainder = blks_needed - data_blocks;
                dgrp_t extra_grps;
@@ -2894,19 +2889,7 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
                overhead = calc_group_overhead(fs, groups-1, old_desc_blocks);
                last_start += EXT2_BLOCKS_PER_GROUP(fs->super) - overhead;
 
-               grp = flex_groups;
-               groups += extra_grps;
-               if (!ext2fs_has_feature_flex_bg(fs->super))
-                       flex_groups = groups;
-               else if (groups > flex_groups) {
-                       dgrp_t r = groups & (flexbg_size - 1);
-
-                       flex_groups = groups + flexbg_size - r;
-                       if (flex_groups > fs->group_desc_count)
-                               flex_groups = fs->group_desc_count;
-               }
-
-               for (; grp < flex_groups; grp++) {
+               for (grp = groups; grp < groups+extra_grps; grp++) {
                        overhead = calc_group_overhead(fs, grp,
                                                       old_desc_blocks);
 
@@ -2914,13 +2897,29 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
                         * again, we need to see how much data we cram into
                         * all of the groups leading up to the last group
                         */
-                       if (grp < groups - 1)
+                       if (grp != (groups + extra_grps - 1))
                                last_start += EXT2_BLOCKS_PER_GROUP(fs->super)
                                        - overhead;
 
                        data_blocks -= overhead;
                }
 
+               groups += extra_grps;
+               extra_groups += extra_grps;
+               if (fs->super->s_feature_incompat
+                       & EXT4_FEATURE_INCOMPAT_FLEX_BG
+                   && extra_groups > flexbg_size) {
+                       /*
+                        * For ext4 we need to allow for up to a flex_bg worth
+                        * of inode tables of slack space so the resize
+                        * operation can be guaranteed to finish.
+                        */
+                       extra_groups = flexbg_size -
+                                               (groups & (flexbg_size - 1));
+                       blks_needed += (fs->inode_blocks_per_group *
+                                       extra_groups);
+                       extra_groups = groups % flexbg_size;
+               }
 #ifdef RESIZE2FS_DEBUG
                if (flags & RESIZE_DEBUG_MIN_CALC)
                        printf("Added %d extra group(s), "
@@ -2931,14 +2930,7 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
        }
 
        /* now for the fun voodoo */
-       grp = groups - 1;
-       if (ext2fs_has_feature_flex_bg(fs->super) &&
-           (grp & ~(flexbg_size - 1)) == 0)
-               grp = grp & ~(flexbg_size - 1);
-       overhead = 0;
-       for (; grp < flex_groups; grp++)
-               overhead += calc_group_overhead(fs, grp, old_desc_blocks);
-
+       overhead = calc_group_overhead(fs, groups-1, old_desc_blocks);
 #ifdef RESIZE2FS_DEBUG
        if (flags & RESIZE_DEBUG_MIN_CALC)
                printf("Last group's overhead is %llu\n", overhead);
@@ -2975,15 +2967,10 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
                printf("Final size of last group is %lld\n", overhead);
 #endif
 
-       /* Add extra slack for bigalloc file systems */
-       if (EXT2FS_CLUSTER_RATIO(fs) > 1)
-               overhead += EXT2FS_CLUSTER_RATIO(fs) * 2;
-
        /*
-        * since our last group doesn't have to be BLOCKS_PER_GROUP
-        * large, we only do groups-1, and then add the number of
-        * blocks needed to handle the group descriptor metadata+data
-        * that we need
+        * since our last group doesn't have to be BLOCKS_PER_GROUP large, we
+        * only do groups-1, and then add the number of blocks needed to
+        * handle the group descriptor metadata+data that we need
         */
        blks_needed = EXT2_GROUPS_TO_BLOCKS(fs->super, groups - 1);
        blks_needed += overhead;
index 3c5e260..034ec9f 100755 (executable)
@@ -9,7 +9,6 @@ truncate()
 }
 
 resize_test () {
-DBG_FLAGS=63
 
 echo $test_description starting > $LOG
 rm -f $TMPFILE
@@ -58,8 +57,8 @@ rm -f $OUT_TMP
 echo $FSCK -fy $TMPFILE >> $LOG 2>&1 
 $FSCK -fy $TMPFILE >> $LOG 2>&1 
 
-echo $RESIZE2FS $RESIZE2FS_OPTS -d $DBG_FLAGS $TMPFILE $SIZE_2 >> $LOG 2>&1
-if ! $RESIZE2FS $RESIZE2FS_OPTS -d $DBG_FLAGS $TMPFILE $SIZE_2 >> $LOG 2>&1
+echo $RESIZE2FS $RESIZE2FS_OPTS -d 31 $TMPFILE $SIZE_2 >> $LOG 2>&1
+if ! $RESIZE2FS $RESIZE2FS_OPTS -d 31 $TMPFILE $SIZE_2 >> $LOG 2>&1
 then
        return 1
 fi
@@ -83,13 +82,8 @@ then
        return 1
 fi
 
-# Uncomment to grab extra debugging image
-#
-#mv $TMPFILE /tmp/foo.img
-#return 0
-
-echo $RESIZE2FS $RESIZE2FS_OPTS -d $DBG_FLAGS -M $TMPFILE $SIZE_2 >> $LOG 2>&1
-if ! $RESIZE2FS $RESIZE2FS_OPTS -d $DBG_FLAGS -M $TMPFILE $SIZE_2 >> $LOG 2>&1
+echo $RESIZE2FS $RESIZE2FS_OPTS -d 31 -M $TMPFILE $SIZE_2 >> $LOG 2>&1
+if ! $RESIZE2FS $RESIZE2FS_OPTS -d 31 -M $TMPFILE $SIZE_2 >> $LOG 2>&1
 then
        return 1
 fi
@@ -113,8 +107,8 @@ then
        return 1
 fi
 
-echo $RESIZE2FS $RESIZE2FS_OPTS -d $DBG_FLAGS -M $TMPFILE $SIZE_2 >> $LOG 2>&1
-if ! $RESIZE2FS $RESIZE2FS_OPTS -d $DBG_FLAGS -M $TMPFILE $SIZE_2 >> $LOG 2>&1
+echo $RESIZE2FS $RESIZE2FS_OPTS -d 31 -M $TMPFILE $SIZE_2 >> $LOG 2>&1
+if ! $RESIZE2FS $RESIZE2FS_OPTS -d 31 -M $TMPFILE $SIZE_2 >> $LOG 2>&1
 then
        return 1
 fi
@@ -138,8 +132,8 @@ then
        return 1
 fi
 
-echo $RESIZE2FS $RESIZE2FS_OPTS -d $DBG_FLAGS -M $TMPFILE $SIZE_2 >> $LOG 2>&1
-if ! $RESIZE2FS $RESIZE2FS_OPTS -d $DBG_FLAGS -M $TMPFILE $SIZE_2 >> $LOG 2>&1
+echo $RESIZE2FS $RESIZE2FS_OPTS -d 31 -M $TMPFILE $SIZE_2 >> $LOG 2>&1
+if ! $RESIZE2FS $RESIZE2FS_OPTS -d 31 -M $TMPFILE $SIZE_2 >> $LOG 2>&1
 then
        return 1
 fi