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>
fs->inode_map);
if (retval) goto errout;
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;
retval = ext2fs_resize_block_bitmap2(new_size - 1,
real_end, fs->block_map);
if (retval) goto errout;
static errcode_t resize2fs_calculate_summary_stats(ext2_filsys fs)
{
errcode_t retval;
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;
- 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;
blk64_t total_clusters_free = 0;
int total_inodes_free = 0;
int group_free = 0;
bitmap_buf = malloc(fs->blocksize);
if (!bitmap_buf)
return ENOMEM;
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;
}
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);
total_clusters_free += group_free;
ext2fs_bg_free_blocks_count_set(fs, group, group_free);
ext2fs_group_desc_csum_set(fs, group);