Skip to content

Commit 579c7e4

Browse files
author
Jaegeuk Kim
committed
Revert "f2fs: clean up w/ sbi->log_sectors_per_block"
This reverts commit bfd4766. Shinichiro Kawasaki reported: When I ran workloads on f2fs using v6.5-rcX with fixes [1][2] and a zoned block devices with 4kb logical block size, I observe mount failure as follows. When I revert this commit, the failure goes away. [ 167.781975][ T1555] F2FS-fs (dm-0): IO Block Size: 4 KB [ 167.890728][ T1555] F2FS-fs (dm-0): Found nat_bits in checkpoint [ 171.482588][ T1555] F2FS-fs (dm-0): Zone without valid block has non-zero write pointer. Reset the write pointer: wp[0x1300,0x8] [ 171.496000][ T1555] F2FS-fs (dm-0): (0) : Unaligned zone reset attempted (block 280000 + 80000) [ 171.505037][ T1555] F2FS-fs (dm-0): Discard zone failed: (errno=-5) The patch replaced "sbi->log_blocksize - SECTOR_SHIFT" with "sbi->log_sectors_per_block". However, I think these two are not equal when the device has 4k logical block size. The former uses Linux kernel sector size 512 byte. The latter use 512b sector size or 4kb sector size depending on the device. mkfs.f2fs obtains logical block size via BLKSSZGET ioctl from the device and reflects it to the value sbi->log_sector_size_per_block. This causes unexpected write pointer calculations in check_zone_write_pointer(). This resulted in unexpected zone reset and the mount failure. [1] https://lkml.kernel.org/linux-f2fs-devel/20230711050101.GA19128@lst.de/ [2] https://lore.kernel.org/linux-f2fs-devel/20230804091556.2372567-1-shinichiro.kawasaki@wdc.com/ Cc: stable@vger.kernel.org Reported-by: Shinichiro Kawasaki <shinichiro.kawasaki@wdc.com> Fixes: bfd4766 ("f2fs: clean up w/ sbi->log_sectors_per_block") Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent 06c2afb commit 579c7e4

1 file changed

Lines changed: 12 additions & 11 deletions

File tree

fs/f2fs/segment.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4846,17 +4846,17 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi,
48464846
{
48474847
unsigned int wp_segno, wp_blkoff, zone_secno, zone_segno, segno;
48484848
block_t zone_block, wp_block, last_valid_block;
4849+
unsigned int log_sectors_per_block = sbi->log_blocksize - SECTOR_SHIFT;
48494850
int i, s, b, ret;
48504851
struct seg_entry *se;
48514852

48524853
if (zone->type != BLK_ZONE_TYPE_SEQWRITE_REQ)
48534854
return 0;
48544855

4855-
wp_block = fdev->start_blk + (zone->wp >> sbi->log_sectors_per_block);
4856+
wp_block = fdev->start_blk + (zone->wp >> log_sectors_per_block);
48564857
wp_segno = GET_SEGNO(sbi, wp_block);
48574858
wp_blkoff = wp_block - START_BLOCK(sbi, wp_segno);
4858-
zone_block = fdev->start_blk + (zone->start >>
4859-
sbi->log_sectors_per_block);
4859+
zone_block = fdev->start_blk + (zone->start >> log_sectors_per_block);
48604860
zone_segno = GET_SEGNO(sbi, zone_block);
48614861
zone_secno = GET_SEC_FROM_SEG(sbi, zone_segno);
48624862

@@ -4906,7 +4906,7 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi,
49064906
"pointer. Reset the write pointer: wp[0x%x,0x%x]",
49074907
wp_segno, wp_blkoff);
49084908
ret = __f2fs_issue_discard_zone(sbi, fdev->bdev, zone_block,
4909-
zone->len >> sbi->log_sectors_per_block);
4909+
zone->len >> log_sectors_per_block);
49104910
if (ret)
49114911
f2fs_err(sbi, "Discard zone failed: %s (errno=%d)",
49124912
fdev->path, ret);
@@ -4967,6 +4967,7 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type)
49674967
struct blk_zone zone;
49684968
unsigned int cs_section, wp_segno, wp_blkoff, wp_sector_off;
49694969
block_t cs_zone_block, wp_block;
4970+
unsigned int log_sectors_per_block = sbi->log_blocksize - SECTOR_SHIFT;
49704971
sector_t zone_sector;
49714972
int err;
49724973

@@ -4978,8 +4979,8 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type)
49784979
return 0;
49794980

49804981
/* report zone for the sector the curseg points to */
4981-
zone_sector = (sector_t)(cs_zone_block - zbd->start_blk) <<
4982-
sbi->log_sectors_per_block;
4982+
zone_sector = (sector_t)(cs_zone_block - zbd->start_blk)
4983+
<< log_sectors_per_block;
49834984
err = blkdev_report_zones(zbd->bdev, zone_sector, 1,
49844985
report_one_zone_cb, &zone);
49854986
if (err != 1) {
@@ -4991,10 +4992,10 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type)
49914992
if (zone.type != BLK_ZONE_TYPE_SEQWRITE_REQ)
49924993
return 0;
49934994

4994-
wp_block = zbd->start_blk + (zone.wp >> sbi->log_sectors_per_block);
4995+
wp_block = zbd->start_blk + (zone.wp >> log_sectors_per_block);
49954996
wp_segno = GET_SEGNO(sbi, wp_block);
49964997
wp_blkoff = wp_block - START_BLOCK(sbi, wp_segno);
4997-
wp_sector_off = zone.wp & GENMASK(sbi->log_sectors_per_block - 1, 0);
4998+
wp_sector_off = zone.wp & GENMASK(log_sectors_per_block - 1, 0);
49984999

49995000
if (cs->segno == wp_segno && cs->next_blkoff == wp_blkoff &&
50005001
wp_sector_off == 0)
@@ -5021,8 +5022,8 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type)
50215022
if (!zbd)
50225023
return 0;
50235024

5024-
zone_sector = (sector_t)(cs_zone_block - zbd->start_blk) <<
5025-
sbi->log_sectors_per_block;
5025+
zone_sector = (sector_t)(cs_zone_block - zbd->start_blk)
5026+
<< log_sectors_per_block;
50265027
err = blkdev_report_zones(zbd->bdev, zone_sector, 1,
50275028
report_one_zone_cb, &zone);
50285029
if (err != 1) {
@@ -5040,7 +5041,7 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type)
50405041
"Reset the zone: curseg[0x%x,0x%x]",
50415042
type, cs->segno, cs->next_blkoff);
50425043
err = __f2fs_issue_discard_zone(sbi, zbd->bdev, cs_zone_block,
5043-
zone.len >> sbi->log_sectors_per_block);
5044+
zone.len >> log_sectors_per_block);
50445045
if (err) {
50455046
f2fs_err(sbi, "Discard zone failed: %s (errno=%d)",
50465047
zbd->path, err);

0 commit comments

Comments
 (0)