On Thu, 17 Jul 2025, Shin'ichiro Kawasaki wrote: > Commit 2df7168717b7 ("dm: Always split write BIOs to zoned device > limits") updates the device-mapper driver to perform splits for the > write BIOs. However, it did not address the cases where DM targets do > not emulate zone append, such as in the cases of dm-linear or dm-flakey. > For these targets, when the write BIOs span across zone boundaries, they > trigger WARN_ON_ONCE(bio_straddles_zones(bio)) in > blk_zone_wplug_handle_write(). This results in I/O errors. The errors > are reproduced by running blktests test case zbd/004 using zoned > dm-linear or dm-flakey devices. > > To avoid the I/O errors, handle the write BIOs regardless whether DM > targets emulate zone append or not, so that all write BIOs are split at > zone boundaries. For that purpose, drop the check for zone append > emulation in dm_zone_bio_needs_split(). Its argument 'md' is no longer > used then drop it also. > > Fixes: 2df7168717b7 ("dm: Always split write BIOs to zoned device limits") > Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@xxxxxxx> > Reviewed-by: Damien Le Moal <dlemoal@xxxxxxxxxx> Reviewed-by: Mikulas Patocka <mpatocka@xxxxxxxxxx> > --- > * Changes from v1: > - Dropped the first paragraph of the commit message > - Improved the block comment > > drivers/md/dm.c | 18 +++++++----------- > 1 file changed, 7 insertions(+), 11 deletions(-) > > diff --git a/drivers/md/dm.c b/drivers/md/dm.c > index ca889328fdfe..abfe0392b5a4 100644 > --- a/drivers/md/dm.c > +++ b/drivers/md/dm.c > @@ -1785,8 +1785,7 @@ static void init_clone_info(struct clone_info *ci, struct dm_io *io, > } > > #ifdef CONFIG_BLK_DEV_ZONED > -static inline bool dm_zone_bio_needs_split(struct mapped_device *md, > - struct bio *bio) > +static inline bool dm_zone_bio_needs_split(struct bio *bio) > { > /* > * Special case the zone operations that cannot or should not be split. > @@ -1802,13 +1801,11 @@ static inline bool dm_zone_bio_needs_split(struct mapped_device *md, > } > > /* > - * Mapped devices that require zone append emulation will use the block > - * layer zone write plugging. In such case, we must split any large BIO > - * to the mapped device limits to avoid potential deadlocks with queue > - * freeze operations. > + * When mapped devices use the block layer zone write plugging, we must > + * split any large BIO to the mapped device limits to not submit BIOs > + * that span zone boundaries and to avoid potential deadlocks with > + * queue freeze operations. > */ > - if (!dm_emulate_zone_append(md)) > - return false; > return bio_needs_zone_write_plugging(bio) || bio_straddles_zones(bio); > } > > @@ -1932,8 +1929,7 @@ static blk_status_t __send_zone_reset_all(struct clone_info *ci) > } > > #else > -static inline bool dm_zone_bio_needs_split(struct mapped_device *md, > - struct bio *bio) > +static inline bool dm_zone_bio_needs_split(struct bio *bio) > { > return false; > } > @@ -1960,7 +1956,7 @@ static void dm_split_and_process_bio(struct mapped_device *md, > > is_abnormal = is_abnormal_io(bio); > if (static_branch_unlikely(&zoned_enabled)) { > - need_split = is_abnormal || dm_zone_bio_needs_split(md, bio); > + need_split = is_abnormal || dm_zone_bio_needs_split(bio); > } else { > need_split = is_abnormal; > } > -- > 2.50.1 >