mirror of
https://github.com/torvalds/linux.git
synced 2026-09-14 08:01:12 +02:00
ext4: fix circular lock dependency in ext4_ext_migrate
Move iput(tmp_inode) after ext4_writepages_up_write() to avoid a
circular lock dependency between s_writepages_rwsem and sb_internal
(freeze protection).
The deadlock scenario:
CPU0 (EXT4_IOC_MIGRATE) CPU1 (orphan cleanup during mount)
---- ----
ext4_ext_migrate()
ext4_writepages_down_write()
s_writepages_rwsem (write)
ext4_evict_inode()
sb_start_intwrite() [sb_internal]
...
ext4_writepages()
s_writepages_rwsem (read) [BLOCKED]
iput(tmp_inode)
ext4_evict_inode()
sb_start_intwrite() [BLOCKED]
The tmp_inode is a temporary inode with nlink=0 created solely for
building the extent tree. Its eviction does not require
s_writepages_rwsem protection, so deferring iput() until after
releasing the rwsem is safe.
Reported-by: syzbot+212e8f62790f8e0bc63b@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=212e8f62790f8e0bc63b
Fixes: cb85f4d23f ("ext4: fix race between writepages and enabling EXT4_EXTENTS_FL")
Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260612005330.1930804-1-yun.zhou@windriver.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
d09811183d
commit
a897682793
|
|
@ -464,6 +464,7 @@ int ext4_ext_migrate(struct inode *inode)
|
|||
if (IS_ERR(tmp_inode)) {
|
||||
retval = PTR_ERR(tmp_inode);
|
||||
ext4_journal_stop(handle);
|
||||
tmp_inode = NULL;
|
||||
goto out_unlock;
|
||||
}
|
||||
/*
|
||||
|
|
@ -591,9 +592,9 @@ int ext4_ext_migrate(struct inode *inode)
|
|||
ext4_journal_stop(handle);
|
||||
out_tmp_inode:
|
||||
unlock_new_inode(tmp_inode);
|
||||
iput(tmp_inode);
|
||||
out_unlock:
|
||||
ext4_writepages_up_write(inode->i_sb, alloc_ctx);
|
||||
iput(tmp_inode);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user