Commit 665d3e0a authored by Baokun Li's avatar Baokun Li Committed by Theodore Ts'o

ext4: reduce unnecessary memory allocation in alloc_flex_gd()

When a large flex_bg file system is resized, the number of groups to be
added may be small, and a large amount of memory that will not be used will
be allocated. Therefore, resize_bg can be set to the size after the number
of new_group_data to be used is aligned upwards to the power of 2. This
does not affect the disk layout after online resize and saves some memory.
Signed-off-by: default avatarBaokun Li <libaokun1@huawei.com>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20231023013057.2117948-5-libaokun1@huawei.comSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent 5d1935ac
...@@ -235,8 +235,10 @@ struct ext4_new_flex_group_data { ...@@ -235,8 +235,10 @@ struct ext4_new_flex_group_data {
* *
* Returns NULL on failure otherwise address of the allocated structure. * Returns NULL on failure otherwise address of the allocated structure.
*/ */
static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned int flexbg_size) static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned int flexbg_size,
ext4_group_t o_group, ext4_group_t n_group)
{ {
ext4_group_t last_group;
struct ext4_new_flex_group_data *flex_gd; struct ext4_new_flex_group_data *flex_gd;
flex_gd = kmalloc(sizeof(*flex_gd), GFP_NOFS); flex_gd = kmalloc(sizeof(*flex_gd), GFP_NOFS);
...@@ -248,6 +250,14 @@ static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned int flexbg_size) ...@@ -248,6 +250,14 @@ static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned int flexbg_size)
else else
flex_gd->resize_bg = flexbg_size; flex_gd->resize_bg = flexbg_size;
/* Avoid allocating large 'groups' array if not needed */
last_group = o_group | (flex_gd->resize_bg - 1);
if (n_group <= last_group)
flex_gd->resize_bg = 1 << fls(n_group - o_group + 1);
else if (n_group - last_group < flex_gd->resize_bg)
flex_gd->resize_bg = 1 << max(fls(last_group - o_group + 1),
fls(n_group - last_group));
flex_gd->groups = kmalloc_array(flex_gd->resize_bg, flex_gd->groups = kmalloc_array(flex_gd->resize_bg,
sizeof(struct ext4_new_group_data), sizeof(struct ext4_new_group_data),
GFP_NOFS); GFP_NOFS);
...@@ -2131,7 +2141,7 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count) ...@@ -2131,7 +2141,7 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
if (err) if (err)
goto out; goto out;
flex_gd = alloc_flex_gd(flexbg_size); flex_gd = alloc_flex_gd(flexbg_size, o_group, n_group);
if (flex_gd == NULL) { if (flex_gd == NULL) {
err = -ENOMEM; err = -ENOMEM;
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment