ext4: fast commit: make s_fc_lock reclaim-safe

s_fc_lock can be acquired from inode eviction and thus is
reclaim unsafe. Since the fast commit path holds s_fc_lock while writing
the commit log, allocations under the lock can enter reclaim and invert
the lock order with fs_reclaim. Add ext4_fc_lock()/ext4_fc_unlock()
helpers which acquire s_fc_lock under memalloc_nofs_save()/restore()
context and use them everywhere so allocations under the lock cannot
recurse into filesystem reclaim.

Fixes: 6593714d67 ("ext4: hold s_fc_lock while during fast commit")
Signed-off-by: Li Chen <me@linux.beauty>
Reviewed-by: Baokun Li <libaokun1@huawei.com>
Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260106120621.440126-1-me@linux.beauty
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
Li Chen
2026-01-06 20:06:21 +08:00
committed by Theodore Ts'o
parent bdc56a9c46
commit 491f2927ae
2 changed files with 44 additions and 23 deletions

View File

@@ -1788,6 +1788,10 @@ struct ext4_sb_info {
* Main fast commit lock. This lock protects accesses to the
* following fields:
* ei->i_fc_list, s_fc_dentry_q, s_fc_q, s_fc_bytes, s_fc_bh.
*
* s_fc_lock can be taken from reclaim context (inode eviction) and is
* thus reclaim unsafe. Use ext4_fc_lock()/ext4_fc_unlock() helpers
* when acquiring / releasing the lock.
*/
struct mutex s_fc_lock;
struct buffer_head *s_fc_bh;
@@ -1832,6 +1836,18 @@ static inline void ext4_writepages_up_write(struct super_block *sb, int ctx)
percpu_up_write(&EXT4_SB(sb)->s_writepages_rwsem);
}
static inline int ext4_fc_lock(struct super_block *sb)
{
mutex_lock(&EXT4_SB(sb)->s_fc_lock);
return memalloc_nofs_save();
}
static inline void ext4_fc_unlock(struct super_block *sb, int ctx)
{
memalloc_nofs_restore(ctx);
mutex_unlock(&EXT4_SB(sb)->s_fc_lock);
}
static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
{
return ino == EXT4_ROOT_INO ||