]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
resize2fs: fix r_bigalloc_big_expand test failure
authorTheodore Ts'o <tytso@mit.edu>
Sun, 28 Apr 2024 01:04:33 +0000 (21:04 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 28 Apr 2024 02:47:33 +0000 (22:47 -0400)
Manually count the number free clusters in the last block group since
it might not be a multiple of 8, and using ext2fs_bitcount() might not
work if bitmap isn't properly padding out.

In addition, when setting up the block bitmap for the resized file
system, resize2fs was setting up the "real end" of the bitmap in units
of blocks instead of clusters.

We didn't notice this problem earlier because of a test failure which
caused the test to be skipped.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
resize/resize2fs.c

index 46540501da764bfd752793e5a1ef8b5e86fa14fb..4daa068b83d6b4674432da382d5bcd0bd5926c93 100644 (file)
@@ -803,8 +803,8 @@ retry:
                                            fs->inode_map);
        if (retval) goto errout;
 
-       real_end = EXT2_GROUPS_TO_BLOCKS(fs->super, fs->group_desc_count) - 1 +
-               fs->super->s_first_data_block;
+       real_end = EXT2_GROUPS_TO_CLUSTERS(fs->super, fs->group_desc_count) -
+               1 + EXT2FS_B2C(fs, fs->super->s_first_data_block);
        retval = ext2fs_resize_block_bitmap2(new_size - 1,
                                             real_end, fs->block_map);
        if (retval) goto errout;
@@ -2843,9 +2843,9 @@ errout:
 static errcode_t resize2fs_calculate_summary_stats(ext2_filsys fs)
 {
        errcode_t       retval;
-       blk64_t         blk = fs->super->s_first_data_block;
+       blk64_t         b, blk = fs->super->s_first_data_block;
        ext2_ino_t      ino;
-       unsigned int    n, group, count;
+       unsigned int    n, max, group, count;
        blk64_t         total_clusters_free = 0;
        int             total_inodes_free = 0;
        int             group_free = 0;
@@ -2858,17 +2858,28 @@ static errcode_t resize2fs_calculate_summary_stats(ext2_filsys fs)
        bitmap_buf = malloc(fs->blocksize);
        if (!bitmap_buf)
                return ENOMEM;
-       for (group = 0; group < fs->group_desc_count;
-            group++) {
+       for (group = 0; group < fs->group_desc_count; group++) {
                retval = ext2fs_get_block_bitmap_range2(fs->block_map,
                        B2C(blk), fs->super->s_clusters_per_group, bitmap_buf);
                if (retval) {
                        free(bitmap_buf);
                        return retval;
                }
-               n = ext2fs_bitcount(bitmap_buf,
-                                   fs->super->s_clusters_per_group / 8);
-               group_free = fs->super->s_clusters_per_group - n;
+               max = ext2fs_group_blocks_count(fs, group) >>
+                      fs->cluster_ratio_bits;
+               if ((group == fs->group_desc_count - 1) && (max & 7)) {
+                       n = 0;
+                       for (b = (fs->super->s_first_data_block +
+                                 (fs->super->s_blocks_per_group * group));
+                            b < ext2fs_blocks_count(fs->super);
+                            b += EXT2FS_CLUSTER_RATIO(fs)) {
+                               if (ext2fs_test_block_bitmap2(fs->block_map, b))
+                                       n++;
+                       }
+               } else {
+                       n = ext2fs_bitcount(bitmap_buf, (max + 7) / 8);
+               }
+               group_free = max - n;
                total_clusters_free += group_free;
                ext2fs_bg_free_blocks_count_set(fs, group, group_free);
                ext2fs_group_desc_csum_set(fs, group);