aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLi Dongyang <dongyangli@ddn.com>2023-09-25 16:08:00 +1000
committerTheodore Ts'o <tytso@mit.edu>2024-04-04 10:49:09 -0400
commitecb37fe311cd67fe7c86eae069551ad15fb20c03 (patch)
tree53e606e480d17b5b6d12dbab1dd04b08901c8b5b
parentf7ef5f3e356d9ee3e20a4c591456da1cf8184814 (diff)
downloade2fsprogs-ecb37fe311cd67fe7c86eae069551ad15fb20c03.tar.gz
mke2fs: set free blocks accurately for groups has GDT
This patch is part of the preparation required to allow GDT blocks expand beyond a single group, it introduces 2 new interfaces: - ext2fs_count_used_blocks(), to return the blocks used in the bitmap range. - ext2fs_reserve_super_and_bgd2() to return blocks used by superblock/GDT blocks for every group, by looking up blocks used. Signed-off-by: Li Dongyang <dongyangli@ddn.com> Reviewed-by: Andreas Dilger <adilger@dilger.ca> Link: https://lore.kernel.org/r/20230925060801.1397581-1-dongyangli@ddn.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--lib/ext2fs/alloc_sb.c28
-rw-r--r--lib/ext2fs/ext2fs.h6
-rw-r--r--lib/ext2fs/gen_bitmap64.c17
-rw-r--r--lib/ext2fs/initialize.c30
-rw-r--r--lib/ext2fs/openfs.c10
-rw-r--r--misc/mke2fs.c2
6 files changed, 73 insertions, 20 deletions
diff --git a/lib/ext2fs/alloc_sb.c b/lib/ext2fs/alloc_sb.c
index 8530b40f6..e92739ecc 100644
--- a/lib/ext2fs/alloc_sb.c
+++ b/lib/ext2fs/alloc_sb.c
@@ -46,8 +46,7 @@ int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
ext2fs_block_bitmap bmap)
{
blk64_t super_blk, old_desc_blk, new_desc_blk;
- blk_t used_blks;
- int old_desc_blocks, num_blocks;
+ blk_t used_blks, old_desc_blocks, num_blocks;
ext2fs_super_and_bgd_loc2(fs, group, &super_blk,
&old_desc_blk, &new_desc_blk, &used_blks);
@@ -79,3 +78,28 @@ int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
return num_blocks ;
}
+
+/*
+ * This function reserves the superblock and block group descriptors
+ * for a given block group and returns the number of blocks used by the
+ * super block and group descriptors by looking up the block bitmap.
+ */
+errcode_t ext2fs_reserve_super_and_bgd2(ext2_filsys fs,
+ dgrp_t group,
+ ext2fs_block_bitmap bmap,
+ blk_t *desc_blocks)
+{
+ blk64_t num_blocks;
+ errcode_t retval = 0;
+
+ ext2fs_reserve_super_and_bgd(fs, group, bmap);
+
+ retval = ext2fs_count_used_blocks(fs,
+ ext2fs_group_first_block2(fs, group),
+ ext2fs_group_last_block2(fs, group),
+ &num_blocks);
+ if (!retval)
+ *desc_blocks = num_blocks;
+
+ return retval;
+}
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 9cea4b69a..e04355134 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -847,6 +847,10 @@ errcode_t ext2fs_alloc_range(ext2_filsys fs, int flags, blk64_t goal,
extern int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
dgrp_t group,
ext2fs_block_bitmap bmap);
+extern errcode_t ext2fs_reserve_super_and_bgd2(ext2_filsys fs,
+ dgrp_t group,
+ ext2fs_block_bitmap bmap,
+ blk_t *desc_blocks);
extern void ext2fs_set_block_alloc_stats_callback(ext2_filsys fs,
void (*func)(ext2_filsys fs,
blk64_t blk,
@@ -1535,6 +1539,8 @@ errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
ext2fs_block_bitmap *bitmap);
errcode_t ext2fs_count_used_clusters(ext2_filsys fs, blk64_t start,
blk64_t end, blk64_t *out);
+errcode_t ext2fs_count_used_blocks(ext2_filsys fs, blk64_t start,
+ blk64_t end, blk64_t *out);
extern unsigned int ext2fs_list_backups(ext2_filsys fs, unsigned int *three,
unsigned int *five, unsigned int *seven);
diff --git a/lib/ext2fs/gen_bitmap64.c b/lib/ext2fs/gen_bitmap64.c
index 4289e8155..5936dcf53 100644
--- a/lib/ext2fs/gen_bitmap64.c
+++ b/lib/ext2fs/gen_bitmap64.c
@@ -945,8 +945,8 @@ errcode_t ext2fs_find_first_set_generic_bmap(ext2fs_generic_bitmap bitmap,
return ENOENT;
}
-errcode_t ext2fs_count_used_clusters(ext2_filsys fs, blk64_t start,
- blk64_t end, blk64_t *out)
+errcode_t ext2fs_count_used_blocks(ext2_filsys fs, blk64_t start,
+ blk64_t end, blk64_t *out)
{
blk64_t next;
blk64_t tot_set = 0;
@@ -976,6 +976,19 @@ errcode_t ext2fs_count_used_clusters(ext2_filsys fs, blk64_t start,
}
if (!retval)
+ *out = tot_set;
+ return retval;
+}
+
+errcode_t ext2fs_count_used_clusters(ext2_filsys fs, blk64_t start,
+ blk64_t end, blk64_t *out)
+{
+ blk64_t tot_set = 0;
+ errcode_t retval = 0;
+
+ retval = ext2fs_count_used_blocks(fs, start, end, &tot_set);
+
+ if (!retval)
*out = EXT2FS_NUM_B2C(fs, tot_set);
return retval;
}
diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c
index d5f9a0f5b..e5286a007 100644
--- a/lib/ext2fs/initialize.c
+++ b/lib/ext2fs/initialize.c
@@ -524,6 +524,15 @@ ipg_retry:
csum_flag = ext2fs_has_group_desc_csum(fs);
reserved_inos = super->s_first_ino;
for (i = 0; i < fs->group_desc_count; i++) {
+ blk_t grp_free_blocks;
+ ext2_ino_t inodes;
+
+ retval = ext2fs_reserve_super_and_bgd2(fs, i,
+ fs->block_map,
+ &numblocks);
+ if (retval)
+ goto cleanup;
+
/*
* Don't set the BLOCK_UNINIT group for the last group
* because the block bitmap needs to be padded.
@@ -533,24 +542,25 @@ ipg_retry:
ext2fs_bg_flags_set(fs, i,
EXT2_BG_BLOCK_UNINIT);
ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT);
- numblocks = super->s_inodes_per_group;
+ inodes = super->s_inodes_per_group;
if (reserved_inos) {
- if (numblocks > reserved_inos) {
- numblocks -= reserved_inos;
+ if (inodes > reserved_inos) {
+ inodes -= reserved_inos;
reserved_inos = 0;
} else {
- reserved_inos -= numblocks;
- numblocks = 0;
+ reserved_inos -= inodes;
+ inodes = 0;
}
}
- ext2fs_bg_itable_unused_set(fs, i, numblocks);
+ ext2fs_bg_itable_unused_set(fs, i, inodes);
}
- numblocks = ext2fs_reserve_super_and_bgd(fs, i, fs->block_map);
- if (fs->super->s_log_groups_per_flex)
+
+ if (!fs->super->s_log_groups_per_flex)
numblocks += 2 + fs->inode_blocks_per_group;
- free_blocks += numblocks;
- ext2fs_bg_free_blocks_count_set(fs, i, numblocks);
+ grp_free_blocks = ext2fs_group_blocks_count(fs, i) - numblocks;
+ free_blocks += grp_free_blocks;
+ ext2fs_bg_free_blocks_count_set(fs, i, grp_free_blocks);
ext2fs_bg_free_inodes_count_set(fs, i, fs->super->s_inodes_per_group);
ext2fs_bg_used_dirs_count_set(fs, i, 0);
ext2fs_group_desc_csum_set(fs, i);
diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c
index fd56a9acd..c3611e0d8 100644
--- a/lib/ext2fs/openfs.c
+++ b/lib/ext2fs/openfs.c
@@ -330,13 +330,13 @@ retry:
}
/* Enforce the block group descriptor size */
- if (!(flags & EXT2_FLAG_IGNORE_SB_ERRORS) &&
- ext2fs_has_feature_64bit(fs->super)) {
+ if (ext2fs_has_feature_64bit(fs->super)) {
unsigned desc_size = fs->super->s_desc_size;
- if ((desc_size < EXT2_MIN_DESC_SIZE_64BIT) ||
- (desc_size > EXT2_MAX_DESC_SIZE) ||
- (desc_size & (desc_size - 1)) != 0) {
+ if (desc_size < EXT2_MIN_DESC_SIZE_64BIT ||
+ (!(flags & EXT2_FLAG_IGNORE_SB_ERRORS) &&
+ ((desc_size > EXT2_MAX_DESC_SIZE) ||
+ (desc_size & (desc_size - 1)) != 0))) {
retval = EXT2_ET_BAD_DESC_SIZE;
goto cleanup;
}
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index aebf050f6..1c5de6869 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -3546,7 +3546,7 @@ no_journal:
fs->super->s_mmp_update_interval);
}
- overhead += fs->super->s_first_data_block;
+ overhead += EXT2FS_NUM_B2C(fs, fs->super->s_first_data_block);
if (!super_only)
fs->super->s_overhead_clusters = overhead;