Skip to content

Commit 3cb88bc

Browse files
kawasakiJaegeuk Kim
authored andcommitted
f2fs: check zone type before sending async reset zone command
The commit 25f9080 ("f2fs: add async reset zone command support") introduced "async reset zone commands" by calling __submit_zone_reset_cmd() in async discard operations. However, __submit_zone_reset_cmd() is called regardless of zone type of discard target zone. When devices have conventional zones, zone reset commands are sent to the conventional zones and cause I/O errors. Avoid the I/O errors by checking that the discard target zone type is sequential write required. If not, handle the discard operation in same manner as non-zoned, regular block devices. For that purpose, add a new helper function f2fs_bdev_index() which gets index of the zone reset target device. Fixes: 25f9080 ("f2fs: add async reset zone command support") Signed-off-by: Shin'ichiro Kawasaki <[email protected]> Reviewed-by: Chao Yu <[email protected]> Signed-off-by: Jaegeuk Kim <[email protected]>
1 parent 025b360 commit 3cb88bc

File tree

2 files changed

+44
-11
lines changed

2 files changed

+44
-11
lines changed

fs/f2fs/f2fs.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4423,6 +4423,22 @@ static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
44234423
}
44244424
#endif
44254425

4426+
static inline int f2fs_bdev_index(struct f2fs_sb_info *sbi,
4427+
struct block_device *bdev)
4428+
{
4429+
int i;
4430+
4431+
if (!f2fs_is_multi_device(sbi))
4432+
return 0;
4433+
4434+
for (i = 0; i < sbi->s_ndevs; i++)
4435+
if (FDEV(i).bdev == bdev)
4436+
return i;
4437+
4438+
WARN_ON(1);
4439+
return -1;
4440+
}
4441+
44264442
static inline bool f2fs_hw_should_discard(struct f2fs_sb_info *sbi)
44274443
{
44284444
return f2fs_sb_has_blkzoned(sbi);

fs/f2fs/segment.c

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,8 +1260,16 @@ static int __submit_discard_cmd(struct f2fs_sb_info *sbi,
12601260

12611261
#ifdef CONFIG_BLK_DEV_ZONED
12621262
if (f2fs_sb_has_blkzoned(sbi) && bdev_is_zoned(bdev)) {
1263-
__submit_zone_reset_cmd(sbi, dc, flag, wait_list, issued);
1264-
return 0;
1263+
int devi = f2fs_bdev_index(sbi, bdev);
1264+
1265+
if (devi < 0)
1266+
return -EINVAL;
1267+
1268+
if (f2fs_blkz_is_seq(sbi, devi, dc->di.start)) {
1269+
__submit_zone_reset_cmd(sbi, dc, flag,
1270+
wait_list, issued);
1271+
return 0;
1272+
}
12651273
}
12661274
#endif
12671275

@@ -1787,15 +1795,24 @@ static void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr)
17871795
dc = __lookup_discard_cmd(sbi, blkaddr);
17881796
#ifdef CONFIG_BLK_DEV_ZONED
17891797
if (dc && f2fs_sb_has_blkzoned(sbi) && bdev_is_zoned(dc->bdev)) {
1790-
/* force submit zone reset */
1791-
if (dc->state == D_PREP)
1792-
__submit_zone_reset_cmd(sbi, dc, REQ_SYNC,
1793-
&dcc->wait_list, NULL);
1794-
dc->ref++;
1795-
mutex_unlock(&dcc->cmd_lock);
1796-
/* wait zone reset */
1797-
__wait_one_discard_bio(sbi, dc);
1798-
return;
1798+
int devi = f2fs_bdev_index(sbi, dc->bdev);
1799+
1800+
if (devi < 0) {
1801+
mutex_unlock(&dcc->cmd_lock);
1802+
return;
1803+
}
1804+
1805+
if (f2fs_blkz_is_seq(sbi, devi, dc->di.start)) {
1806+
/* force submit zone reset */
1807+
if (dc->state == D_PREP)
1808+
__submit_zone_reset_cmd(sbi, dc, REQ_SYNC,
1809+
&dcc->wait_list, NULL);
1810+
dc->ref++;
1811+
mutex_unlock(&dcc->cmd_lock);
1812+
/* wait zone reset */
1813+
__wait_one_discard_bio(sbi, dc);
1814+
return;
1815+
}
17991816
}
18001817
#endif
18011818
if (dc) {

0 commit comments

Comments
 (0)