aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2024-04-27 21:04:33 -0400
committerTheodore Ts'o <tytso@mit.edu>2024-04-27 22:47:33 -0400
commitd43fb24ca0db24cdb3d53d0cc0bf8c211f416b78 (patch)
tree917dd54b9c816e2a53044a4ec6922b56866a8df8
parent53618d8de3639766ad485ab4c6a4194de5ec2b43 (diff)
downloade2fsprogs-d43fb24ca0db24cdb3d53d0cc0bf8c211f416b78.tar.gz
resize2fs: fix r_bigalloc_big_expand test failure
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>
-rw-r--r--resize/resize2fs.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index 46540501d..4daa068b8 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -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);