mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 16:12:59 +02:00
f2fs: Prevent s_writer rw_sem count mismatch in f2fs_evict_inode
If f2fs_evict_inode is called between freeze_super and thaw_super, the
s_writer rwsem count may become negative, resulting in hang.
CPU1 CPU2
f2fs_resize_fs() f2fs_evict_inode()
f2fs_freeze
set SBI_IS_FREEZING
skip sb_start_intwrite
f2fs_unfreeze
clear SBI_IS_FREEZING
sb_end_intwrite
To solve this problem, the call to sb_end_write is determined by whether
sb_start_intwrite is called, rather than the current freezing status.
Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
Reviewed-by: Sunmin Jeong <s_min.jeong@samsung.com>
Signed-off-by: Yeongjin Gil <youngjin.gil@samsung.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
ee745e4736
commit
3127f1010c
|
|
@ -804,6 +804,7 @@ void f2fs_evict_inode(struct inode *inode)
|
|||
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||
nid_t xnid = fi->i_xattr_nid;
|
||||
int err = 0;
|
||||
bool freeze_protected = false;
|
||||
|
||||
f2fs_abort_atomic_write(inode, true);
|
||||
|
||||
|
|
@ -843,8 +844,10 @@ void f2fs_evict_inode(struct inode *inode)
|
|||
f2fs_remove_ino_entry(sbi, inode->i_ino, UPDATE_INO);
|
||||
f2fs_remove_ino_entry(sbi, inode->i_ino, FLUSH_INO);
|
||||
|
||||
if (!is_sbi_flag_set(sbi, SBI_IS_FREEZING))
|
||||
if (!is_sbi_flag_set(sbi, SBI_IS_FREEZING)) {
|
||||
sb_start_intwrite(inode->i_sb);
|
||||
freeze_protected = true;
|
||||
}
|
||||
set_inode_flag(inode, FI_NO_ALLOC);
|
||||
i_size_write(inode, 0);
|
||||
retry:
|
||||
|
|
@ -887,7 +890,7 @@ void f2fs_evict_inode(struct inode *inode)
|
|||
if (dquot_initialize_needed(inode))
|
||||
set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
|
||||
}
|
||||
if (!is_sbi_flag_set(sbi, SBI_IS_FREEZING))
|
||||
if (freeze_protected)
|
||||
sb_end_intwrite(inode->i_sb);
|
||||
no_delete:
|
||||
dquot_drop(inode);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user