f2fs: Fix the race condition of resize flag between resizefs
authorZhang Qilong <zhangqilong3@huawei.com>
Tue, 18 Oct 2022 02:45:32 +0000 (10:45 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Fri, 28 Oct 2022 03:25:59 +0000 (20:25 -0700)
Because the set/clear SBI_IS_RESIZEFS flag not between any locks,
In the following case:
  thread1 thread2
   ->ioctl(resizefs)
    ->set RESIZEFS flag  ->ioctl(resizefs)
    ...                      ->set RESIZEFS flag
    ->clear RESIZEFS flag
       ->resizefs stream
    # No RESIZEFS flag in the stream

Also before freeze_super, the resizefs not started, we should not set
the SBI_IS_RESIZEFS flag.

So move the set/clear SBI_IS_RESIZEFS flag between the cp_mutex and
gc_lock.

Fixes: b4b10061ef98 ("f2fs: refactor resize_fs to avoid meta updates in progress")
Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
Signed-off-by: Zhang Qilong <zhangqilong3@huawei.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/gc.c

index dab7942..7b4be41 100644 (file)
@@ -2134,8 +2134,6 @@ out_unlock:
        if (err)
                return err;
 
-       set_sbi_flag(sbi, SBI_IS_RESIZEFS);
-
        freeze_super(sbi->sb);
        f2fs_down_write(&sbi->gc_lock);
        f2fs_down_write(&sbi->cp_global_sem);
@@ -2151,6 +2149,7 @@ out_unlock:
        if (err)
                goto out_err;
 
+       set_sbi_flag(sbi, SBI_IS_RESIZEFS);
        err = free_segment_range(sbi, secs, false);
        if (err)
                goto recover_out;
@@ -2174,6 +2173,7 @@ out_unlock:
                f2fs_commit_super(sbi, false);
        }
 recover_out:
+       clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
        if (err) {
                set_sbi_flag(sbi, SBI_NEED_FSCK);
                f2fs_err(sbi, "resize_fs failed, should run fsck to repair!");
@@ -2186,6 +2186,5 @@ out_err:
        f2fs_up_write(&sbi->cp_global_sem);
        f2fs_up_write(&sbi->gc_lock);
        thaw_super(sbi->sb);
-       clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
        return err;
 }