Skip to content

Commit

Permalink
f2fs: Prevent s_writer rw_sem count mismatch in f2fs_evict_inode
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Sunmin Jeong <[email protected]>
Signed-off-by: Yeongjin Gil <[email protected]>
Reviewed-by: Chao Yu <[email protected]>
Signed-off-by: Jaegeuk Kim <[email protected]>
  • Loading branch information
YeongjinGil authored and Jaegeuk Kim committed Apr 2, 2024
1 parent ff55757 commit 772a226
Showing 1 changed file with 5 additions and 2 deletions.
7 changes: 5 additions & 2 deletions fs/f2fs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 772a226

Please sign in to comment.