mirror of
https://github.com/torvalds/linux.git
synced 2026-09-26 18:12:03 +02:00
ext4: skip extra isize expansion during mount to prevent deadlock
ext4_try_to_expand_extra_isize() is called from __ext4_mark_inode_dirty()
while holding an active jbd2 handle. During mount (!SB_ACTIVE), the
expand path may move xattrs to external blocks and release ea_inodes via
iput(). When !SB_ACTIVE, iput() calls write_inode_now() which acquires
s_writepages_rwsem, creating a circular lock dependency:
s_writepages_rwsem --> jbd2_handle --> xattr_sem --> s_writepages_rwsem
This can be triggered via:
ext4_process_orphan() -> ext4_truncate() -> ext4_mark_inode_dirty()
-> ext4_try_to_expand_extra_isize()
or:
ext4_evict_inode() -> ext4_mark_inode_dirty()
-> ext4_try_to_expand_extra_isize()
Skip expansion when !SB_ACTIVE. This is a minor loss of functionality
(extra isize won't grow for these inodes during mount), which e2fsck
can resolve later if needed.
Reported-by: syzbot+5d19358d7eb30ffb0cc5@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=5d19358d7eb30ffb0cc5
Fixes: c8585c6fca ("ext4: fix races between changing inode journal mode and ext4_writepages")
Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260623061903.2148767-1-yun.zhou@windriver.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
9333cc809f
commit
7461c60b9c
|
|
@ -6511,6 +6511,16 @@ static int ext4_try_to_expand_extra_isize(struct inode *inode,
|
|||
if (ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND))
|
||||
return -EOVERFLOW;
|
||||
|
||||
/*
|
||||
* Skip expansion during mount (!SB_ACTIVE). Expanding extra isize
|
||||
* may move xattrs to external blocks and release ea_inodes via iput.
|
||||
* When !SB_ACTIVE, iput triggers write_inode_now() which acquires
|
||||
* s_writepages_rwsem, causing a deadlock with the caller's active
|
||||
* jbd2 handle (lock order: s_writepages_rwsem -> jbd2_handle).
|
||||
*/
|
||||
if (unlikely(!(inode->i_sb->s_flags & SB_ACTIVE)))
|
||||
return -EBUSY;
|
||||
|
||||
/*
|
||||
* In nojournal mode, we can immediately attempt to expand
|
||||
* the inode. When journaled, we first need to obtain extra
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user