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
|
0x800 SBI_QUOTA_SKIP_FLUSH skip flushing quota in current CP
|
||||||
0x1000 SBI_QUOTA_NEED_REPAIR quota file may be corrupted
|
0x1000 SBI_QUOTA_NEED_REPAIR quota file may be corrupted
|
||||||
0x2000 SBI_IS_RESIZEFS resizefs is in process
|
0x2000 SBI_IS_RESIZEFS resizefs is in process
|
||||||
|
0x4000 SBI_IS_FREEZING freefs is in process
|
||||||
====== ===================== =================================
|
====== ===================== =================================
|
||||||
|
|
||||||
What: /sys/fs/f2fs/<disk>/ckpt_thread_ioprio
|
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_SKIP_FLUSH, /* skip flushing quota in current CP */
|
||||||
SBI_QUOTA_NEED_REPAIR, /* quota file may be corrupted */
|
SBI_QUOTA_NEED_REPAIR, /* quota file may be corrupted */
|
||||||
SBI_IS_RESIZEFS, /* resizefs is in process */
|
SBI_IS_RESIZEFS, /* resizefs is in process */
|
||||||
|
SBI_IS_FREEZING, /* freezefs is in process */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@@ -764,6 +764,7 @@ 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, UPDATE_INO);
|
||||||
f2fs_remove_ino_entry(sbi, inode->i_ino, FLUSH_INO);
|
f2fs_remove_ino_entry(sbi, inode->i_ino, FLUSH_INO);
|
||||||
|
|
||||||
|
if (!is_sbi_flag_set(sbi, SBI_IS_FREEZING))
|
||||||
sb_start_intwrite(inode->i_sb);
|
sb_start_intwrite(inode->i_sb);
|
||||||
set_inode_flag(inode, FI_NO_ALLOC);
|
set_inode_flag(inode, FI_NO_ALLOC);
|
||||||
i_size_write(inode, 0);
|
i_size_write(inode, 0);
|
||||||
@@ -795,6 +796,7 @@ retry:
|
|||||||
if (dquot_initialize_needed(inode))
|
if (dquot_initialize_needed(inode))
|
||||||
set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
|
set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
|
||||||
}
|
}
|
||||||
|
if (!is_sbi_flag_set(sbi, SBI_IS_FREEZING))
|
||||||
sb_end_intwrite(inode->i_sb);
|
sb_end_intwrite(inode->i_sb);
|
||||||
no_delete:
|
no_delete:
|
||||||
dquot_drop(inode);
|
dquot_drop(inode);
|
||||||
|
@@ -1558,11 +1558,15 @@ static int f2fs_freeze(struct super_block *sb)
|
|||||||
/* ensure no checkpoint required */
|
/* ensure no checkpoint required */
|
||||||
if (!llist_empty(&F2FS_SB(sb)->cprc_info.issue_list))
|
if (!llist_empty(&F2FS_SB(sb)->cprc_info.issue_list))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* to avoid deadlock on f2fs_evict_inode->SB_FREEZE_FS */
|
||||||
|
set_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int f2fs_unfreeze(struct super_block *sb)
|
static int f2fs_unfreeze(struct super_block *sb)
|
||||||
{
|
{
|
||||||
|
clear_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user