summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYeongjin Gil <youngjin.gil@samsung.com>2024-03-22 07:16:39 +0300
committerJaegeuk Kim <jaegeuk@kernel.org>2024-03-26 19:52:26 +0300
commit3127f1010c9b27d925e83081d413ea7fc361abb0 (patch)
tree98fff95dfbadc3412f971cab9ad0efa6af63a6fa
parentee745e4736fbf33079d0d0808e1343c2280fd59a (diff)
downloadlinux-3127f1010c9b27d925e83081d413ea7fc361abb0.tar.xz
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>
-rw-r--r--fs/f2fs/inode.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index c26effdce9aa..12b1fef31f43 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -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 @@ retry:
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);