BACKPORT: f2fs: don't get FREEZE lock in f2fs_evict_inode in frozen fs
Let's purge inode cache in order to avoid the below deadlock. [freeze test] shrinkder freeze_super - pwercpu_down_write(SB_FREEZE_FS) - super_cache_scan - down_read(&sb->s_umount) - prune_icache_sb - dispose_list - evict - f2fs_evict_inode thaw_super - down_write(&sb->s_umount); - __percpu_down_read(SB_FREEZE_FS) Bug: 242127451 Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> Change-Id: Ifa01aca90eab6968c5e511fb3819854121aa9b7c (cherry picked from commit e3d44a0028f58cd1dcba053120652e1a1ea6ce12)
This commit is contained in:
@@ -432,6 +432,7 @@ Description: Show status of f2fs superblock in real time.
|
||||
0x800 SBI_QUOTA_SKIP_FLUSH skip flushing quota in current CP
|
||||
0x1000 SBI_QUOTA_NEED_REPAIR quota file may be corrupted
|
||||
0x2000 SBI_IS_RESIZEFS resizefs is in process
|
||||
0x4000 SBI_IS_FREEZING freefs is in process
|
||||
====== ===================== =================================
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/ckpt_thread_ioprio
|
||||
|
@@ -1247,6 +1247,7 @@ enum {
|
||||
SBI_QUOTA_SKIP_FLUSH, /* skip flushing quota in current CP */
|
||||
SBI_QUOTA_NEED_REPAIR, /* quota file may be corrupted */
|
||||
SBI_IS_RESIZEFS, /* resizefs is in process */
|
||||
SBI_IS_FREEZING, /* freezefs is in process */
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@@ -764,7 +764,8 @@ 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);
|
||||
|
||||
sb_start_intwrite(inode->i_sb);
|
||||
if (!is_sbi_flag_set(sbi, SBI_IS_FREEZING))
|
||||
sb_start_intwrite(inode->i_sb);
|
||||
set_inode_flag(inode, FI_NO_ALLOC);
|
||||
i_size_write(inode, 0);
|
||||
retry:
|
||||
@@ -795,7 +796,8 @@ retry:
|
||||
if (dquot_initialize_needed(inode))
|
||||
set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
|
||||
}
|
||||
sb_end_intwrite(inode->i_sb);
|
||||
if (!is_sbi_flag_set(sbi, SBI_IS_FREEZING))
|
||||
sb_end_intwrite(inode->i_sb);
|
||||
no_delete:
|
||||
dquot_drop(inode);
|
||||
|
||||
|
@@ -1558,11 +1558,15 @@ static int f2fs_freeze(struct super_block *sb)
|
||||
/* ensure no checkpoint required */
|
||||
if (!llist_empty(&F2FS_SB(sb)->cprc_info.issue_list))
|
||||
return -EINVAL;
|
||||
|
||||
/* to avoid deadlock on f2fs_evict_inode->SB_FREEZE_FS */
|
||||
set_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int f2fs_unfreeze(struct super_block *sb)
|
||||
{
|
||||
clear_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user