mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-16 04:04:06 +00:00
f2fs: don't get FREEZE lock in f2fs_evict_inode in frozen fs
[ Upstream commit ba900534f8
]
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)
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
5ce33f5850
commit
165a92fda3
5 changed files with 11 additions and 2 deletions
|
@ -425,6 +425,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
|
||||
|
|
|
@ -338,6 +338,7 @@ static char *s_flag[] = {
|
|||
[SBI_QUOTA_SKIP_FLUSH] = " quota_skip_flush",
|
||||
[SBI_QUOTA_NEED_REPAIR] = " quota_need_repair",
|
||||
[SBI_IS_RESIZEFS] = " resizefs",
|
||||
[SBI_IS_FREEZING] = " freezefs",
|
||||
};
|
||||
|
||||
static int stat_show(struct seq_file *s, void *v)
|
||||
|
|
|
@ -1253,6 +1253,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 {
|
||||
|
|
|
@ -769,7 +769,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:
|
||||
|
@ -800,7 +801,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);
|
||||
|
||||
|
|
|
@ -1663,11 +1663,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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue