aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/super.c
diff options
context:
space:
mode:
authorChao Yu <yuchao0@huawei.com>2019-02-19 03:23:53 -0500
committerJaegeuk Kim <jaegeuk@kernel.org>2019-03-12 21:59:17 -0400
commitaa2c8c43e4a5c242f5b0331c8b7a941b85f9435a (patch)
tree770a3dd298dc739d2b3b1aecdfd21316d54d8993 /fs/f2fs/super.c
parentbc73a4b2414f2914fa895747166312b1527a97bb (diff)
f2fs: fix to retry fill_super only if recovery failed
With current retry mechanism in f2fs_fill_super, first fill_super fails due to no memory, then second fill_super runs w/o recovery, if we succeed, we may lose fsynced data, it doesn't make sense. Let's retry fill_super only if it occurs non-ENOMEM error during recovery. Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/super.c')
-rw-r--r--fs/f2fs/super.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 230845221c74..45121190a2ba 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -3053,10 +3053,11 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
3053 struct f2fs_super_block *raw_super; 3053 struct f2fs_super_block *raw_super;
3054 struct inode *root; 3054 struct inode *root;
3055 int err; 3055 int err;
3056 bool retry = true, need_fsck = false; 3056 bool skip_recovery = false, need_fsck = false;
3057 char *options = NULL; 3057 char *options = NULL;
3058 int recovery, i, valid_super_block; 3058 int recovery, i, valid_super_block;
3059 struct curseg_info *seg_i; 3059 struct curseg_info *seg_i;
3060 int retry_cnt = 1;
3060 3061
3061try_onemore: 3062try_onemore:
3062 err = -EINVAL; 3063 err = -EINVAL;
@@ -3345,7 +3346,7 @@ try_onemore:
3345 goto free_meta; 3346 goto free_meta;
3346 3347
3347 if (unlikely(is_set_ckpt_flags(sbi, CP_DISABLED_FLAG))) 3348 if (unlikely(is_set_ckpt_flags(sbi, CP_DISABLED_FLAG)))
3348 goto skip_recovery; 3349 goto reset_checkpoint;
3349 3350
3350 /* recover fsynced data */ 3351 /* recover fsynced data */
3351 if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) { 3352 if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) {
@@ -3362,11 +3363,13 @@ try_onemore:
3362 if (need_fsck) 3363 if (need_fsck)
3363 set_sbi_flag(sbi, SBI_NEED_FSCK); 3364 set_sbi_flag(sbi, SBI_NEED_FSCK);
3364 3365
3365 if (!retry) 3366 if (skip_recovery)
3366 goto skip_recovery; 3367 goto reset_checkpoint;
3367 3368
3368 err = f2fs_recover_fsync_data(sbi, false); 3369 err = f2fs_recover_fsync_data(sbi, false);
3369 if (err < 0) { 3370 if (err < 0) {
3371 if (err != -ENOMEM)
3372 skip_recovery = true;
3370 need_fsck = true; 3373 need_fsck = true;
3371 f2fs_msg(sb, KERN_ERR, 3374 f2fs_msg(sb, KERN_ERR,
3372 "Cannot recover all fsync data errno=%d", err); 3375 "Cannot recover all fsync data errno=%d", err);
@@ -3382,7 +3385,7 @@ try_onemore:
3382 goto free_meta; 3385 goto free_meta;
3383 } 3386 }
3384 } 3387 }
3385skip_recovery: 3388reset_checkpoint:
3386 /* f2fs_recover_fsync_data() cleared this already */ 3389 /* f2fs_recover_fsync_data() cleared this already */
3387 clear_sbi_flag(sbi, SBI_POR_DOING); 3390 clear_sbi_flag(sbi, SBI_POR_DOING);
3388 3391
@@ -3428,7 +3431,7 @@ skip_recovery:
3428sync_free_meta: 3431sync_free_meta:
3429 /* safe to flush all the data */ 3432 /* safe to flush all the data */
3430 sync_filesystem(sbi->sb); 3433 sync_filesystem(sbi->sb);
3431 retry = false; 3434 retry_cnt = 0;
3432 3435
3433free_meta: 3436free_meta:
3434#ifdef CONFIG_QUOTA 3437#ifdef CONFIG_QUOTA
@@ -3488,8 +3491,8 @@ free_sbi:
3488 kvfree(sbi); 3491 kvfree(sbi);
3489 3492
3490 /* give only one another chance */ 3493 /* give only one another chance */
3491 if (retry) { 3494 if (retry_cnt > 0 && skip_recovery) {
3492 retry = false; 3495 retry_cnt--;
3493 shrink_dcache_sb(sb); 3496 shrink_dcache_sb(sb);
3494 goto try_onemore; 3497 goto try_onemore;
3495 } 3498 }