2024-02-16 22:32:17

by Jaegeuk Kim

[permalink] [raw]
Subject: [PATCH 1/2] f2fs: fix write pointers all the time

Even if the roll forward recovery stopped due to any error, we have to fix
the write pointers in order to mount the disk from the previous checkpoint.

Signed-off-by: Jaegeuk Kim <[email protected]>
---
fs/f2fs/recovery.c | 2 +-
fs/f2fs/super.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index b3baec666afe..8bbecb5f9323 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -913,7 +913,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
* and the f2fs is not read only, check and fix zoned block devices'
* write pointer consistency.
*/
- if (!err && fix_curseg_write_pointer && !f2fs_readonly(sbi->sb) &&
+ if (fix_curseg_write_pointer && !f2fs_readonly(sbi->sb) &&
f2fs_sb_has_blkzoned(sbi)) {
err = f2fs_fix_curseg_write_pointer(sbi);
if (!err)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 0b3b18715bec..a2b7a5c448b5 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4656,7 +4656,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
* If the f2fs is not readonly and fsync data recovery succeeds,
* check zoned block devices' write pointer consistency.
*/
- if (!err && !f2fs_readonly(sb) && f2fs_sb_has_blkzoned(sbi)) {
+ if (!f2fs_readonly(sb) && f2fs_sb_has_blkzoned(sbi)) {
err = f2fs_check_write_pointer(sbi);
if (err)
goto free_meta;
--
2.44.0.rc0.258.g7320e95886-goog



2024-02-16 22:32:22

by Jaegeuk Kim

[permalink] [raw]
Subject: [PATCH 2/2] f2fs: print zone status in string and some log

No functional change, but add some more logs.

Signed-off-by: Jaegeuk Kim <[email protected]>
---
fs/f2fs/segment.c | 34 ++++++++++++++++++++++++----------
fs/f2fs/super.c | 1 +
2 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 4e248be030a6..3bbb80487b13 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -4855,6 +4855,16 @@ static int sanity_check_curseg(struct f2fs_sb_info *sbi)
}

#ifdef CONFIG_BLK_DEV_ZONED
+const char *f2fs_zone_status[BLK_ZONE_COND_OFFLINE + 1] = {
+ [BLK_ZONE_COND_NOT_WP] = "NOT_WP",
+ [BLK_ZONE_COND_EMPTY] = "EMPTY",
+ [BLK_ZONE_COND_IMP_OPEN] = "IMPLICITE_OPEN",
+ [BLK_ZONE_COND_EXP_OPEN] = "EXPLICITE_OPEN",
+ [BLK_ZONE_COND_CLOSED] = "CLOSED",
+ [BLK_ZONE_COND_READONLY] = "READONLY",
+ [BLK_ZONE_COND_FULL] = "FULL",
+ [BLK_ZONE_COND_OFFLINE] = "OFFLINE",
+};

static int check_zone_write_pointer(struct f2fs_sb_info *sbi,
struct f2fs_dev_info *fdev,
@@ -4871,18 +4881,22 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi,
zone_block = fdev->start_blk + (zone->start >> log_sectors_per_block);
zone_segno = GET_SEGNO(sbi, zone_block);

+ /*
+ * Get # of valid block of the zone.
+ */
+ valid_block_cnt = get_valid_blocks(sbi, zone_segno, true);
+
/*
* Skip check of zones cursegs point to, since
* fix_curseg_write_pointer() checks them.
*/
if (zone_segno >= MAIN_SEGS(sbi) ||
- IS_CURSEC(sbi, GET_SEC_FROM_SEG(sbi, zone_segno)))
+ IS_CURSEC(sbi, GET_SEC_FROM_SEG(sbi, zone_segno))) {
+ f2fs_notice(sbi, "Open zones: valid block[0x%x,0x%x] cond[%s]",
+ zone_segno, valid_block_cnt,
+ f2fs_zone_status[zone->cond]);
return 0;
-
- /*
- * Get # of valid block of the zone.
- */
- valid_block_cnt = get_valid_blocks(sbi, zone_segno, true);
+ }

if ((!valid_block_cnt && zone->cond == BLK_ZONE_COND_EMPTY) ||
(valid_block_cnt && zone->cond == BLK_ZONE_COND_FULL))
@@ -4890,8 +4904,8 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi,

if (!valid_block_cnt) {
f2fs_notice(sbi, "Zone without valid block has non-zero write "
- "pointer. Reset the write pointer: cond[0x%x]",
- zone->cond);
+ "pointer. Reset the write pointer: cond[%s]",
+ f2fs_zone_status[zone->cond]);
ret = __f2fs_issue_discard_zone(sbi, fdev->bdev, zone_block,
zone->len >> log_sectors_per_block);
if (ret)
@@ -4908,8 +4922,8 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi,
* selected for write operation until it get discarded.
*/
f2fs_notice(sbi, "Valid blocks are not aligned with write "
- "pointer: valid block[0x%x,0x%x] cond[0x%x]",
- zone_segno, valid_block_cnt, zone->cond);
+ "pointer: valid block[0x%x,0x%x] cond[%s]",
+ zone_segno, valid_block_cnt, f2fs_zone_status[zone->cond]);

ret = blkdev_zone_mgmt(fdev->bdev, REQ_OP_ZONE_FINISH,
zone->start, zone->len, GFP_NOFS);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index a2b7a5c448b5..cb597b8e8ec5 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4657,6 +4657,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
* check zoned block devices' write pointer consistency.
*/
if (!f2fs_readonly(sb) && f2fs_sb_has_blkzoned(sbi)) {
+ f2fs_notice(sbi, "Checking entire write pointers");
err = f2fs_check_write_pointer(sbi);
if (err)
goto free_meta;
--
2.44.0.rc0.258.g7320e95886-goog