Skip to content

Commit ba90053

Browse files
author
Jaegeuk Kim
committed
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) Reviewed-by: Chao Yu <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]>
1 parent d13732c commit ba90053

File tree

5 files changed

+11
-2
lines changed

5 files changed

+11
-2
lines changed

Documentation/ABI/testing/sysfs-fs-f2fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ Description: Show status of f2fs superblock in real time.
458458
0x800 SBI_QUOTA_SKIP_FLUSH skip flushing quota in current CP
459459
0x1000 SBI_QUOTA_NEED_REPAIR quota file may be corrupted
460460
0x2000 SBI_IS_RESIZEFS resizefs is in process
461+
0x4000 SBI_IS_FREEZING freefs is in process
461462
====== ===================== =================================
462463

463464
What: /sys/fs/f2fs/<disk>/ckpt_thread_ioprio

fs/f2fs/debug.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ static char *s_flag[] = {
338338
[SBI_QUOTA_SKIP_FLUSH] = " quota_skip_flush",
339339
[SBI_QUOTA_NEED_REPAIR] = " quota_need_repair",
340340
[SBI_IS_RESIZEFS] = " resizefs",
341+
[SBI_IS_FREEZING] = " freezefs",
341342
};
342343

343344
static int stat_show(struct seq_file *s, void *v)

fs/f2fs/f2fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,7 @@ enum {
12931293
SBI_QUOTA_SKIP_FLUSH, /* skip flushing quota in current CP */
12941294
SBI_QUOTA_NEED_REPAIR, /* quota file may be corrupted */
12951295
SBI_IS_RESIZEFS, /* resizefs is in process */
1296+
SBI_IS_FREEZING, /* freezefs is in process */
12961297
};
12971298

12981299
enum {

fs/f2fs/inode.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,8 @@ void f2fs_evict_inode(struct inode *inode)
778778
f2fs_remove_ino_entry(sbi, inode->i_ino, UPDATE_INO);
779779
f2fs_remove_ino_entry(sbi, inode->i_ino, FLUSH_INO);
780780

781-
sb_start_intwrite(inode->i_sb);
781+
if (!is_sbi_flag_set(sbi, SBI_IS_FREEZING))
782+
sb_start_intwrite(inode->i_sb);
782783
set_inode_flag(inode, FI_NO_ALLOC);
783784
i_size_write(inode, 0);
784785
retry:
@@ -809,7 +810,8 @@ void f2fs_evict_inode(struct inode *inode)
809810
if (dquot_initialize_needed(inode))
810811
set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
811812
}
812-
sb_end_intwrite(inode->i_sb);
813+
if (!is_sbi_flag_set(sbi, SBI_IS_FREEZING))
814+
sb_end_intwrite(inode->i_sb);
813815
no_delete:
814816
dquot_drop(inode);
815817

fs/f2fs/super.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,11 +1663,15 @@ static int f2fs_freeze(struct super_block *sb)
16631663
/* ensure no checkpoint required */
16641664
if (!llist_empty(&F2FS_SB(sb)->cprc_info.issue_list))
16651665
return -EINVAL;
1666+
1667+
/* to avoid deadlock on f2fs_evict_inode->SB_FREEZE_FS */
1668+
set_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING);
16661669
return 0;
16671670
}
16681671

16691672
static int f2fs_unfreeze(struct super_block *sb)
16701673
{
1674+
clear_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING);
16711675
return 0;
16721676
}
16731677

0 commit comments

Comments
 (0)