Commit 9f792ab8 authored by Daeho Jeong's avatar Daeho Jeong Committed by Jaegeuk Kim

f2fs: clean up zones when not successfully unmounted

We can't trust write pointers when the previous mount was not
successfully unmounted.
Signed-off-by: default avatarDaeho Jeong <daehojeong@google.com>
Reviewed-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 6f560c0f
...@@ -4910,22 +4910,31 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi, ...@@ -4910,22 +4910,31 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi,
} }
/* /*
* The write pointer matches with the valid blocks or * When safely unmounted in the previous mount, we can trust write
* already points to the end of the zone. * pointers. Otherwise, finish zones.
*/ */
if ((last_valid_block + 1 == wp_block) || if (is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) {
(zone->wp == zone->start + zone->len))
return 0;
if (last_valid_block + 1 == zone_block) {
/* /*
* If there is no valid block in the zone and if write pointer * The write pointer matches with the valid blocks or
* is not at zone start, reset the write pointer. * already points to the end of the zone.
*/ */
f2fs_notice(sbi, if ((last_valid_block + 1 == wp_block) ||
"Zone without valid block has non-zero write " (zone->wp == zone->start + zone->len))
"pointer. Reset the write pointer: wp[0x%x,0x%x]", return 0;
wp_segno, wp_blkoff); }
if (last_valid_block + 1 == zone_block) {
if (is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) {
/*
* If there is no valid block in the zone and if write
* pointer is not at zone start, reset the write
* pointer.
*/
f2fs_notice(sbi,
"Zone without valid block has non-zero write "
"pointer. Reset the write pointer: wp[0x%x,0x%x]",
wp_segno, wp_blkoff);
}
ret = __f2fs_issue_discard_zone(sbi, fdev->bdev, zone_block, ret = __f2fs_issue_discard_zone(sbi, fdev->bdev, zone_block,
zone->len >> log_sectors_per_block); zone->len >> log_sectors_per_block);
if (ret) if (ret)
...@@ -4935,18 +4944,20 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi, ...@@ -4935,18 +4944,20 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi,
return ret; return ret;
} }
/* if (is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) {
* If there are valid blocks and the write pointer doesn't /*
* match with them, we need to report the inconsistency and * If there are valid blocks and the write pointer doesn't match
* fill the zone till the end to close the zone. This inconsistency * with them, we need to report the inconsistency and fill
* does not cause write error because the zone will not be selected * the zone till the end to close the zone. This inconsistency
* for write operation until it get discarded. * does not cause write error because the zone will not be
*/ * 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] wp[0x%x,0x%x]", f2fs_notice(sbi, "Valid blocks are not aligned with write "
GET_SEGNO(sbi, last_valid_block), "pointer: valid block[0x%x,0x%x] wp[0x%x,0x%x]",
GET_BLKOFF_FROM_SEG0(sbi, last_valid_block), GET_SEGNO(sbi, last_valid_block),
wp_segno, wp_blkoff); GET_BLKOFF_FROM_SEG0(sbi, last_valid_block),
wp_segno, wp_blkoff);
}
ret = blkdev_zone_mgmt(fdev->bdev, REQ_OP_ZONE_FINISH, ret = blkdev_zone_mgmt(fdev->bdev, REQ_OP_ZONE_FINISH,
zone->start, zone->len, GFP_NOFS); zone->start, zone->len, GFP_NOFS);
...@@ -5020,18 +5031,27 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type) ...@@ -5020,18 +5031,27 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type)
if (zone.type != BLK_ZONE_TYPE_SEQWRITE_REQ) if (zone.type != BLK_ZONE_TYPE_SEQWRITE_REQ)
return 0; return 0;
wp_block = zbd->start_blk + (zone.wp >> log_sectors_per_block); /*
wp_segno = GET_SEGNO(sbi, wp_block); * When safely unmounted in the previous mount, we could use current
wp_blkoff = wp_block - START_BLOCK(sbi, wp_segno); * segments. Otherwise, allocate new sections.
wp_sector_off = zone.wp & GENMASK(log_sectors_per_block - 1, 0); */
if (is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) {
if (cs->segno == wp_segno && cs->next_blkoff == wp_blkoff && wp_block = zbd->start_blk + (zone.wp >> log_sectors_per_block);
wp_sector_off == 0) wp_segno = GET_SEGNO(sbi, wp_block);
return 0; wp_blkoff = wp_block - START_BLOCK(sbi, wp_segno);
wp_sector_off = zone.wp & GENMASK(log_sectors_per_block - 1, 0);
if (cs->segno == wp_segno && cs->next_blkoff == wp_blkoff &&
wp_sector_off == 0)
return 0;
f2fs_notice(sbi, "Unaligned curseg[%d] with write pointer: " f2fs_notice(sbi, "Unaligned curseg[%d] with write pointer: "
"curseg[0x%x,0x%x] wp[0x%x,0x%x]", "curseg[0x%x,0x%x] wp[0x%x,0x%x]", type, cs->segno,
type, cs->segno, cs->next_blkoff, wp_segno, wp_blkoff); cs->next_blkoff, wp_segno, wp_blkoff);
} else {
f2fs_notice(sbi, "Not successfully unmounted in the previous "
"mount");
}
f2fs_notice(sbi, "Assign new section to curseg[%d]: " f2fs_notice(sbi, "Assign new section to curseg[%d]: "
"curseg[0x%x,0x%x]", type, cs->segno, cs->next_blkoff); "curseg[0x%x,0x%x]", type, cs->segno, cs->next_blkoff);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment