Skip to content

Commit 9f792ab

Browse files
Daeho JeongJaegeuk Kim
authored andcommitted
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: Daeho Jeong <[email protected]> Reviewed-by: Chao Yu <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]>
1 parent 6f560c0 commit 9f792ab

File tree

1 file changed

+56
-36
lines changed

1 file changed

+56
-36
lines changed

fs/f2fs/segment.c

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4910,22 +4910,31 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi,
49104910
}
49114911

49124912
/*
4913-
* The write pointer matches with the valid blocks or
4914-
* already points to the end of the zone.
4913+
* When safely unmounted in the previous mount, we can trust write
4914+
* pointers. Otherwise, finish zones.
49154915
*/
4916-
if ((last_valid_block + 1 == wp_block) ||
4917-
(zone->wp == zone->start + zone->len))
4918-
return 0;
4919-
4920-
if (last_valid_block + 1 == zone_block) {
4916+
if (is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) {
49214917
/*
4922-
* If there is no valid block in the zone and if write pointer
4923-
* is not at zone start, reset the write pointer.
4918+
* The write pointer matches with the valid blocks or
4919+
* already points to the end of the zone.
49244920
*/
4925-
f2fs_notice(sbi,
4926-
"Zone without valid block has non-zero write "
4927-
"pointer. Reset the write pointer: wp[0x%x,0x%x]",
4928-
wp_segno, wp_blkoff);
4921+
if ((last_valid_block + 1 == wp_block) ||
4922+
(zone->wp == zone->start + zone->len))
4923+
return 0;
4924+
}
4925+
4926+
if (last_valid_block + 1 == zone_block) {
4927+
if (is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) {
4928+
/*
4929+
* If there is no valid block in the zone and if write
4930+
* pointer is not at zone start, reset the write
4931+
* pointer.
4932+
*/
4933+
f2fs_notice(sbi,
4934+
"Zone without valid block has non-zero write "
4935+
"pointer. Reset the write pointer: wp[0x%x,0x%x]",
4936+
wp_segno, wp_blkoff);
4937+
}
49294938
ret = __f2fs_issue_discard_zone(sbi, fdev->bdev, zone_block,
49304939
zone->len >> log_sectors_per_block);
49314940
if (ret)
@@ -4935,18 +4944,20 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi,
49354944
return ret;
49364945
}
49374946

4938-
/*
4939-
* If there are valid blocks and the write pointer doesn't
4940-
* match with them, we need to report the inconsistency and
4941-
* fill the zone till the end to close the zone. This inconsistency
4942-
* does not cause write error because the zone will not be selected
4943-
* for write operation until it get discarded.
4944-
*/
4945-
f2fs_notice(sbi, "Valid blocks are not aligned with write pointer: "
4946-
"valid block[0x%x,0x%x] wp[0x%x,0x%x]",
4947-
GET_SEGNO(sbi, last_valid_block),
4948-
GET_BLKOFF_FROM_SEG0(sbi, last_valid_block),
4949-
wp_segno, wp_blkoff);
4947+
if (is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) {
4948+
/*
4949+
* If there are valid blocks and the write pointer doesn't match
4950+
* with them, we need to report the inconsistency and fill
4951+
* the zone till the end to close the zone. This inconsistency
4952+
* does not cause write error because the zone will not be
4953+
* selected for write operation until it get discarded.
4954+
*/
4955+
f2fs_notice(sbi, "Valid blocks are not aligned with write "
4956+
"pointer: valid block[0x%x,0x%x] wp[0x%x,0x%x]",
4957+
GET_SEGNO(sbi, last_valid_block),
4958+
GET_BLKOFF_FROM_SEG0(sbi, last_valid_block),
4959+
wp_segno, wp_blkoff);
4960+
}
49504961

49514962
ret = blkdev_zone_mgmt(fdev->bdev, REQ_OP_ZONE_FINISH,
49524963
zone->start, zone->len, GFP_NOFS);
@@ -5020,18 +5031,27 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type)
50205031
if (zone.type != BLK_ZONE_TYPE_SEQWRITE_REQ)
50215032
return 0;
50225033

5023-
wp_block = zbd->start_blk + (zone.wp >> log_sectors_per_block);
5024-
wp_segno = GET_SEGNO(sbi, wp_block);
5025-
wp_blkoff = wp_block - START_BLOCK(sbi, wp_segno);
5026-
wp_sector_off = zone.wp & GENMASK(log_sectors_per_block - 1, 0);
5027-
5028-
if (cs->segno == wp_segno && cs->next_blkoff == wp_blkoff &&
5029-
wp_sector_off == 0)
5030-
return 0;
5034+
/*
5035+
* When safely unmounted in the previous mount, we could use current
5036+
* segments. Otherwise, allocate new sections.
5037+
*/
5038+
if (is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) {
5039+
wp_block = zbd->start_blk + (zone.wp >> log_sectors_per_block);
5040+
wp_segno = GET_SEGNO(sbi, wp_block);
5041+
wp_blkoff = wp_block - START_BLOCK(sbi, wp_segno);
5042+
wp_sector_off = zone.wp & GENMASK(log_sectors_per_block - 1, 0);
5043+
5044+
if (cs->segno == wp_segno && cs->next_blkoff == wp_blkoff &&
5045+
wp_sector_off == 0)
5046+
return 0;
50315047

5032-
f2fs_notice(sbi, "Unaligned curseg[%d] with write pointer: "
5033-
"curseg[0x%x,0x%x] wp[0x%x,0x%x]",
5034-
type, cs->segno, cs->next_blkoff, wp_segno, wp_blkoff);
5048+
f2fs_notice(sbi, "Unaligned curseg[%d] with write pointer: "
5049+
"curseg[0x%x,0x%x] wp[0x%x,0x%x]", type, cs->segno,
5050+
cs->next_blkoff, wp_segno, wp_blkoff);
5051+
} else {
5052+
f2fs_notice(sbi, "Not successfully unmounted in the previous "
5053+
"mount");
5054+
}
50355055

50365056
f2fs_notice(sbi, "Assign new section to curseg[%d]: "
50375057
"curseg[0x%x,0x%x]", type, cs->segno, cs->next_blkoff);

0 commit comments

Comments
 (0)