diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index e8b6b89bddb865..59d0472013f437 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -696,6 +696,8 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi) /* clear Orphan Flag */ clear_ckpt_flags(sbi, CP_ORPHAN_PRESENT_FLAG); out: + set_sbi_flag(sbi, SBI_IS_RECOVERED); + #ifdef CONFIG_QUOTA /* Turn quotas off */ if (quota_enabled) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index e146e6c443e843..ecb73514227693 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1089,6 +1089,7 @@ enum { SBI_NEED_SB_WRITE, /* need to recover superblock */ SBI_NEED_CP, /* need to checkpoint */ SBI_IS_SHUTDOWN, /* shutdown by ioctl */ + SBI_IS_RECOVERED, /* recovered orphan/data */ }; enum { diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 12a3293bcbc943..9a8579fb3a30db 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -698,11 +698,15 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) /* let's drop all the directory inodes for clean checkpoint */ destroy_fsync_dnodes(&dir_list); - if (!err && need_writecp) { - struct cp_control cpc = { - .reason = CP_RECOVERY, - }; - err = f2fs_write_checkpoint(sbi, &cpc); + if (need_writecp) { + set_sbi_flag(sbi, SBI_IS_RECOVERED); + + if (!err) { + struct cp_control cpc = { + .reason = CP_RECOVERY, + }; + err = f2fs_write_checkpoint(sbi, &cpc); + } } kmem_cache_destroy(fsync_entry_slab); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index d0d016f213079e..287c9fe9fff9a2 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3188,6 +3188,9 @@ static void kill_f2fs_super(struct super_block *sb) }; f2fs_write_checkpoint(sbi, &cpc); } + + if (is_sbi_flag_set(sbi, SBI_IS_RECOVERED) && f2fs_readonly(sb)) + sb->s_flags &= ~SB_RDONLY; } kill_block_super(sb); }