Skip to content

Commit 4865c76

Browse files
jankaratytso
authored andcommitted
ext4: always allocate blocks only from groups inode can use
For filesystems with more than 2^32 blocks inodes using indirect block based format cannot use blocks beyond the 32-bit limit. ext4_mb_scan_groups_linear() takes care to not select these unsupported groups for such inodes however other functions selecting groups for allocation don't. So far this is harmless because the other selection functions are used only with mb_optimize_scan and this is currently disabled for inodes with indirect blocks however in the following patch we want to enable mb_optimize_scan regardless of inode format. Reviewed-by: Baokun Li <libaokun1@huawei.com> Reviewed-by: Zhang Yi <yi.zhang@huawei.com> Signed-off-by: Jan Kara <jack@suse.cz> Acked-by: Pedro Falcato <pfalcato@suse.de> Cc: stable@kernel.org Link: https://patch.msgid.link/20260114182836.14120-3-jack@suse.cz Signed-off-by: Theodore Ts'o <tytso@mit.edu>
1 parent 94a8cea commit 4865c76

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

fs/ext4/mballoc.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -892,14 +892,29 @@ mb_update_avg_fragment_size(struct super_block *sb, struct ext4_group_info *grp)
892892
}
893893
}
894894

895+
static ext4_group_t ext4_get_allocation_groups_count(
896+
struct ext4_allocation_context *ac)
897+
{
898+
ext4_group_t ngroups = ext4_get_groups_count(ac->ac_sb);
899+
900+
/* non-extent files are limited to low blocks/groups */
901+
if (!(ext4_test_inode_flag(ac->ac_inode, EXT4_INODE_EXTENTS)))
902+
ngroups = EXT4_SB(ac->ac_sb)->s_blockfile_groups;
903+
904+
/* Pairs with smp_wmb() in ext4_update_super() */
905+
smp_rmb();
906+
907+
return ngroups;
908+
}
909+
895910
static int ext4_mb_scan_groups_xa_range(struct ext4_allocation_context *ac,
896911
struct xarray *xa,
897912
ext4_group_t start, ext4_group_t end)
898913
{
899914
struct super_block *sb = ac->ac_sb;
900915
struct ext4_sb_info *sbi = EXT4_SB(sb);
901916
enum criteria cr = ac->ac_criteria;
902-
ext4_group_t ngroups = ext4_get_groups_count(sb);
917+
ext4_group_t ngroups = ext4_get_allocation_groups_count(ac);
903918
unsigned long group = start;
904919
struct ext4_group_info *grp;
905920

@@ -951,7 +966,7 @@ static int ext4_mb_scan_groups_p2_aligned(struct ext4_allocation_context *ac,
951966
ext4_group_t start, end;
952967

953968
start = group;
954-
end = ext4_get_groups_count(ac->ac_sb);
969+
end = ext4_get_allocation_groups_count(ac);
955970
wrap_around:
956971
for (i = ac->ac_2order; i < MB_NUM_ORDERS(ac->ac_sb); i++) {
957972
ret = ext4_mb_scan_groups_largest_free_order_range(ac, i,
@@ -1001,7 +1016,7 @@ static int ext4_mb_scan_groups_goal_fast(struct ext4_allocation_context *ac,
10011016
ext4_group_t start, end;
10021017

10031018
start = group;
1004-
end = ext4_get_groups_count(ac->ac_sb);
1019+
end = ext4_get_allocation_groups_count(ac);
10051020
wrap_around:
10061021
i = mb_avg_fragment_size_order(ac->ac_sb, ac->ac_g_ex.fe_len);
10071022
for (; i < MB_NUM_ORDERS(ac->ac_sb); i++) {
@@ -1083,7 +1098,7 @@ static int ext4_mb_scan_groups_best_avail(struct ext4_allocation_context *ac,
10831098
min_order = fls(ac->ac_o_ex.fe_len);
10841099

10851100
start = group;
1086-
end = ext4_get_groups_count(ac->ac_sb);
1101+
end = ext4_get_allocation_groups_count(ac);
10871102
wrap_around:
10881103
for (i = order; i >= min_order; i--) {
10891104
int frag_order;
@@ -1182,11 +1197,7 @@ static int ext4_mb_scan_groups(struct ext4_allocation_context *ac)
11821197
int ret = 0;
11831198
ext4_group_t start;
11841199
struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
1185-
ext4_group_t ngroups = ext4_get_groups_count(ac->ac_sb);
1186-
1187-
/* non-extent files are limited to low blocks/groups */
1188-
if (!(ext4_test_inode_flag(ac->ac_inode, EXT4_INODE_EXTENTS)))
1189-
ngroups = sbi->s_blockfile_groups;
1200+
ext4_group_t ngroups = ext4_get_allocation_groups_count(ac);
11901201

11911202
/* searching for the right group start from the goal value specified */
11921203
start = ac->ac_g_ex.fe_group;

0 commit comments

Comments
 (0)