Skip to content

Commit 1e7bef5

Browse files
Daeho JeongJaegeuk Kim
authored andcommitted
f2fs: finish previous checkpoints before returning from remount
Flush remaining checkpoint requests at the end of remount, since a new checkpoint would be triggered while remount and we need to take care of it before returning from remount, in order to avoid the below race condition. - Thread - checkpoint thread do_remount() down_write(&sb->s_umount); f2fs_remount() f2fs_disable_checkpoint(sbi) -> add checkpoints to the list block_operations() down_read_trylock(&sb->s_umount) = 0 up_write(&sb->s_umount); f2fs_quota_sync() dquot_writeback_dquots() WARN_ON_ONCE(!rwsem_is_locked(&sb->s_umount)); Signed-off-by: Daeho Jeong <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]>
1 parent 9b4c8dd commit 1e7bef5

File tree

1 file changed

+32
-27
lines changed

1 file changed

+32
-27
lines changed

fs/f2fs/super.c

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,9 +2319,9 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
23192319
unsigned long old_sb_flags;
23202320
int err;
23212321
bool need_restart_gc = false, need_stop_gc = false;
2322-
bool need_restart_ckpt = false, need_stop_ckpt = false;
23232322
bool need_restart_flush = false, need_stop_flush = false;
23242323
bool need_restart_discard = false, need_stop_discard = false;
2324+
bool need_enable_checkpoint = false, need_disable_checkpoint = false;
23252325
bool no_read_extent_cache = !test_opt(sbi, READ_EXTENT_CACHE);
23262326
bool no_age_extent_cache = !test_opt(sbi, AGE_EXTENT_CACHE);
23272327
bool enable_checkpoint = !test_opt(sbi, DISABLE_CHECKPOINT);
@@ -2485,24 +2485,6 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
24852485
clear_sbi_flag(sbi, SBI_IS_CLOSE);
24862486
}
24872487

2488-
if ((*flags & SB_RDONLY) || test_opt(sbi, DISABLE_CHECKPOINT) ||
2489-
!test_opt(sbi, MERGE_CHECKPOINT)) {
2490-
f2fs_stop_ckpt_thread(sbi);
2491-
need_restart_ckpt = true;
2492-
} else {
2493-
/* Flush if the prevous checkpoint, if exists. */
2494-
f2fs_flush_ckpt_thread(sbi);
2495-
2496-
err = f2fs_start_ckpt_thread(sbi);
2497-
if (err) {
2498-
f2fs_err(sbi,
2499-
"Failed to start F2FS issue_checkpoint_thread (%d)",
2500-
err);
2501-
goto restore_gc;
2502-
}
2503-
need_stop_ckpt = true;
2504-
}
2505-
25062488
/*
25072489
* We stop issue flush thread if FS is mounted as RO
25082490
* or if flush_merge is not passed in mount option.
@@ -2514,7 +2496,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
25142496
} else {
25152497
err = f2fs_create_flush_cmd_control(sbi);
25162498
if (err)
2517-
goto restore_ckpt;
2499+
goto restore_gc;
25182500
need_stop_flush = true;
25192501
}
25202502

@@ -2536,8 +2518,31 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
25362518
err = f2fs_disable_checkpoint(sbi);
25372519
if (err)
25382520
goto restore_discard;
2521+
need_enable_checkpoint = true;
25392522
} else {
25402523
f2fs_enable_checkpoint(sbi);
2524+
need_disable_checkpoint = true;
2525+
}
2526+
}
2527+
2528+
/*
2529+
* Place this routine at the end, since a new checkpoint would be
2530+
* triggered while remount and we need to take care of it before
2531+
* returning from remount.
2532+
*/
2533+
if ((*flags & SB_RDONLY) || test_opt(sbi, DISABLE_CHECKPOINT) ||
2534+
!test_opt(sbi, MERGE_CHECKPOINT)) {
2535+
f2fs_stop_ckpt_thread(sbi);
2536+
} else {
2537+
/* Flush if the prevous checkpoint, if exists. */
2538+
f2fs_flush_ckpt_thread(sbi);
2539+
2540+
err = f2fs_start_ckpt_thread(sbi);
2541+
if (err) {
2542+
f2fs_err(sbi,
2543+
"Failed to start F2FS issue_checkpoint_thread (%d)",
2544+
err);
2545+
goto restore_checkpoint;
25412546
}
25422547
}
25432548

@@ -2555,6 +2560,13 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
25552560
adjust_unusable_cap_perc(sbi);
25562561
*flags = (*flags & ~SB_LAZYTIME) | (sb->s_flags & SB_LAZYTIME);
25572562
return 0;
2563+
restore_checkpoint:
2564+
if (need_enable_checkpoint) {
2565+
f2fs_enable_checkpoint(sbi);
2566+
} else if (need_disable_checkpoint) {
2567+
if (f2fs_disable_checkpoint(sbi))
2568+
f2fs_warn(sbi, "checkpoint has not been disabled");
2569+
}
25582570
restore_discard:
25592571
if (need_restart_discard) {
25602572
if (f2fs_start_discard_thread(sbi))
@@ -2570,13 +2582,6 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
25702582
clear_opt(sbi, FLUSH_MERGE);
25712583
f2fs_destroy_flush_cmd_control(sbi, false);
25722584
}
2573-
restore_ckpt:
2574-
if (need_restart_ckpt) {
2575-
if (f2fs_start_ckpt_thread(sbi))
2576-
f2fs_warn(sbi, "background ckpt thread has stopped");
2577-
} else if (need_stop_ckpt) {
2578-
f2fs_stop_ckpt_thread(sbi);
2579-
}
25802585
restore_gc:
25812586
if (need_restart_gc) {
25822587
if (f2fs_start_gc_thread(sbi))

0 commit comments

Comments
 (0)