Skip to content

Commit 1015035

Browse files
Sheng YongJaegeuk Kim
authored andcommitted
f2fs: fix changing cursegs if recovery fails on zoned device
Fsync data recovery attempts to check and fix write pointer consistency of cursegs and all other zones. If the write pointers of cursegs are unaligned, cursegs are changed to new sections. If recovery fails, zone write pointers are still checked and fixed, but the latest checkpoint cannot be written back. Additionally, retry- mount skips recovery and rolls back to reuse the old cursegs whose zones are already finished. This can lead to unaligned write later. This patch addresses the issue by leaving writer pointers untouched if recovery fails. When retry-mount is performed, cursegs and other zones are checked and fixed after skipping recovery. Signed-off-by: Song Feng <songfeng@oppo.com> Signed-off-by: Yongpeng Yang <yangyongpeng1@oppo.com> Signed-off-by: Sheng Yong <shengyong@oppo.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent a35749b commit 1015035

File tree

4 files changed

+28
-28
lines changed

4 files changed

+28
-28
lines changed

fs/f2fs/f2fs.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3775,8 +3775,7 @@ void f2fs_write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
37753775
int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
37763776
unsigned int val, int alloc);
37773777
void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc);
3778-
int f2fs_fix_curseg_write_pointer(struct f2fs_sb_info *sbi);
3779-
int f2fs_check_write_pointer(struct f2fs_sb_info *sbi);
3778+
int f2fs_check_and_fix_write_pointer(struct f2fs_sb_info *sbi);
37803779
int f2fs_build_segment_manager(struct f2fs_sb_info *sbi);
37813780
void f2fs_destroy_segment_manager(struct f2fs_sb_info *sbi);
37823781
int __init f2fs_create_segment_manager_caches(void);

fs/f2fs/recovery.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -899,13 +899,8 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
899899
* and the f2fs is not read only, check and fix zoned block devices'
900900
* write pointer consistency.
901901
*/
902-
if (f2fs_sb_has_blkzoned(sbi) && !f2fs_readonly(sbi->sb)) {
903-
int err2 = f2fs_fix_curseg_write_pointer(sbi);
904-
905-
if (!err2)
906-
err2 = f2fs_check_write_pointer(sbi);
907-
if (err2)
908-
err = err2;
902+
if (!err) {
903+
err = f2fs_check_and_fix_write_pointer(sbi);
909904
ret = err;
910905
}
911906

fs/f2fs/segment.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5246,7 +5246,7 @@ static int report_one_zone_cb(struct blk_zone *zone, unsigned int idx,
52465246
return 0;
52475247
}
52485248

5249-
static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type)
5249+
static int do_fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type)
52505250
{
52515251
struct curseg_info *cs = CURSEG_I(sbi, type);
52525252
struct f2fs_dev_info *zbd;
@@ -5351,12 +5351,12 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type)
53515351
return 0;
53525352
}
53535353

5354-
int f2fs_fix_curseg_write_pointer(struct f2fs_sb_info *sbi)
5354+
static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi)
53555355
{
53565356
int i, ret;
53575357

53585358
for (i = 0; i < NR_PERSISTENT_LOG; i++) {
5359-
ret = fix_curseg_write_pointer(sbi, i);
5359+
ret = do_fix_curseg_write_pointer(sbi, i);
53605360
if (ret)
53615361
return ret;
53625362
}
@@ -5379,7 +5379,7 @@ static int check_zone_write_pointer_cb(struct blk_zone *zone, unsigned int idx,
53795379
return check_zone_write_pointer(args->sbi, args->fdev, zone);
53805380
}
53815381

5382-
int f2fs_check_write_pointer(struct f2fs_sb_info *sbi)
5382+
static int check_write_pointer(struct f2fs_sb_info *sbi)
53835383
{
53845384
int i, ret;
53855385
struct check_zone_write_pointer_args args;
@@ -5399,6 +5399,20 @@ int f2fs_check_write_pointer(struct f2fs_sb_info *sbi)
53995399
return 0;
54005400
}
54015401

5402+
int f2fs_check_and_fix_write_pointer(struct f2fs_sb_info *sbi)
5403+
{
5404+
int ret;
5405+
5406+
if (!f2fs_sb_has_blkzoned(sbi) || f2fs_readonly(sbi->sb))
5407+
return 0;
5408+
5409+
f2fs_notice(sbi, "Checking entire write pointers");
5410+
ret = fix_curseg_write_pointer(sbi);
5411+
if (!ret)
5412+
ret = check_write_pointer(sbi);
5413+
return ret;
5414+
}
5415+
54025416
/*
54035417
* Return the number of usable blocks in a segment. The number of blocks
54045418
* returned is always equal to the number of blocks in a segment for
@@ -5435,12 +5449,7 @@ static inline unsigned int f2fs_usable_zone_blks_in_seg(
54355449
return BLKS_PER_SEG(sbi);
54365450
}
54375451
#else
5438-
int f2fs_fix_curseg_write_pointer(struct f2fs_sb_info *sbi)
5439-
{
5440-
return 0;
5441-
}
5442-
5443-
int f2fs_check_write_pointer(struct f2fs_sb_info *sbi)
5452+
int f2fs_check_and_fix_write_pointer(struct f2fs_sb_info *sbi)
54445453
{
54455454
return 0;
54465455
}

fs/f2fs/super.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4774,16 +4774,13 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
47744774
reset_checkpoint:
47754775
/*
47764776
* If the f2fs is not readonly and fsync data recovery succeeds,
4777-
* check zoned block devices' write pointer consistency.
4777+
* write pointer consistency of cursegs and other zones are already
4778+
* checked and fixed during recovery. However, if recovery fails,
4779+
* write pointers are left untouched, and retry-mount should check
4780+
* them here.
47784781
*/
4779-
if (f2fs_sb_has_blkzoned(sbi) && !f2fs_readonly(sb)) {
4780-
int err2;
4781-
4782-
f2fs_notice(sbi, "Checking entire write pointers");
4783-
err2 = f2fs_check_write_pointer(sbi);
4784-
if (err2)
4785-
err = err2;
4786-
}
4782+
if (skip_recovery)
4783+
err = f2fs_check_and_fix_write_pointer(sbi);
47874784
if (err)
47884785
goto free_meta;
47894786

0 commit comments

Comments
 (0)