Skip to content

Commit b12f423

Browse files
zhangyi089tytso
authored andcommitted
ext4: limit the maximum folio order
In environments with a page size of 64KB, the maximum size of a folio can reach up to 128MB. Consequently, during the write-back of folios, the 'rsv_blocks' will be overestimated to 1,577, which can make pressure on the journal space where the journal is small. This can easily exceed the limit of a single transaction. Besides, an excessively large folio is meaningless and will instead increase the overhead of traversing the bhs within the folio. Therefore, limit the maximum order of a folio to 2048 filesystem blocks. Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org> Reported-by: Joseph Qi <jiangqi903@gmail.com> Closes: https://lore.kernel.org/linux-ext4/CA+G9fYsyYQ3ZL4xaSg1-Tt5Evto7Zd+hgNWZEa9cQLbahA1+xg@mail.gmail.com/ Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Tested-by: Joseph Qi <joseph.qi@linux.alibaba.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20250707140814.542883-12-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
1 parent 5137d6c commit b12f423

3 files changed

Lines changed: 21 additions & 6 deletions

File tree

fs/ext4/ext4.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3020,7 +3020,7 @@ int ext4_walk_page_buffers(handle_t *handle,
30203020
struct buffer_head *bh));
30213021
int do_journal_get_write_access(handle_t *handle, struct inode *inode,
30223022
struct buffer_head *bh);
3023-
bool ext4_should_enable_large_folio(struct inode *inode);
3023+
void ext4_set_inode_mapping_order(struct inode *inode);
30243024
#define FALL_BACK_TO_NONDELALLOC 1
30253025
#define CONVERT_INLINE_DATA 2
30263026

fs/ext4/ialloc.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,8 +1335,7 @@ struct inode *__ext4_new_inode(struct mnt_idmap *idmap,
13351335
}
13361336
}
13371337

1338-
if (ext4_should_enable_large_folio(inode))
1339-
mapping_set_large_folios(inode->i_mapping);
1338+
ext4_set_inode_mapping_order(inode);
13401339

13411340
ext4_update_inode_fsync_trans(handle, inode, 1);
13421341

fs/ext4/inode.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5179,7 +5179,7 @@ static int check_igot_inode(struct inode *inode, ext4_iget_flags flags,
51795179
return -EFSCORRUPTED;
51805180
}
51815181

5182-
bool ext4_should_enable_large_folio(struct inode *inode)
5182+
static bool ext4_should_enable_large_folio(struct inode *inode)
51835183
{
51845184
struct super_block *sb = inode->i_sb;
51855185

@@ -5196,6 +5196,22 @@ bool ext4_should_enable_large_folio(struct inode *inode)
51965196
return true;
51975197
}
51985198

5199+
/*
5200+
* Limit the maximum folio order to 2048 blocks to prevent overestimation
5201+
* of reserve handle credits during the folio writeback in environments
5202+
* where the PAGE_SIZE exceeds 4KB.
5203+
*/
5204+
#define EXT4_MAX_PAGECACHE_ORDER(i) \
5205+
umin(MAX_PAGECACHE_ORDER, (11 + (i)->i_blkbits - PAGE_SHIFT))
5206+
void ext4_set_inode_mapping_order(struct inode *inode)
5207+
{
5208+
if (!ext4_should_enable_large_folio(inode))
5209+
return;
5210+
5211+
mapping_set_folio_order_range(inode->i_mapping, 0,
5212+
EXT4_MAX_PAGECACHE_ORDER(inode));
5213+
}
5214+
51995215
struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
52005216
ext4_iget_flags flags, const char *function,
52015217
unsigned int line)
@@ -5513,8 +5529,8 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
55135529
ret = -EFSCORRUPTED;
55145530
goto bad_inode;
55155531
}
5516-
if (ext4_should_enable_large_folio(inode))
5517-
mapping_set_large_folios(inode->i_mapping);
5532+
5533+
ext4_set_inode_mapping_order(inode);
55185534

55195535
ret = check_igot_inode(inode, flags, function, line);
55205536
/*

0 commit comments

Comments
 (0)