]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
dm: split write BIOs on zone boundaries when zone append is not emulated
authorShin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Thu, 17 Jul 2025 10:35:39 +0000 (19:35 +0900)
committerJens Axboe <axboe@kernel.dk>
Thu, 17 Jul 2025 12:03:03 +0000 (06:03 -0600)
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@wdc.com>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Mikulas Patocka <mpatocka@redhat.com>
Link: https://lore.kernel.org/r/20250717103539.37279-1-shinichiro.kawasaki@wdc.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/md/dm.c

index ca889328fdfef8589a484297044be1d0083f03c8..abfe0392b5a47ecd55b5d0b8f31529ec96b20280 100644 (file)
@@ -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;
        }