Skip to content

Commit dddf305

Browse files
author
Mike Snitzer
committed
dm: fix zoned locking imbalance due to needless check in clone_endio
After the commit ca52248 ("dm: pass NULL bdev to bio_alloc_clone"), clone_endio() only calls dm_zone_endio() when DM targets remap the clone bio's bdev to something other than the md->disk->part0 default. However, if a DM target (e.g. dm-crypt) stacked ontop of a dm-zoned does not remap the clone bio using bio_set_dev() then dm_zone_endio() is not called at completion of the bios and zone locks are not properly unlocked. This triggers a hang, in dm_zone_map_bio(), when blktests block/004 is run for dm-crypt on zoned block devices. To avoid the hang, simply remove the clone_endio() check that verifies the target remapped the clone bio to a device other than the default. Fixes: ca52248 ("dm: pass NULL bdev to bio_alloc_clone") Reported-by: Shin'ichiro Kawasaki <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent d5a37b1 commit dddf305

File tree

1 file changed

+11
-15
lines changed

1 file changed

+11
-15
lines changed

drivers/md/dm.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,23 +1016,19 @@ static void clone_endio(struct bio *bio)
10161016
struct dm_io *io = tio->io;
10171017
struct mapped_device *md = io->md;
10181018

1019-
if (likely(bio->bi_bdev != md->disk->part0)) {
1020-
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
1021-
1022-
if (unlikely(error == BLK_STS_TARGET)) {
1023-
if (bio_op(bio) == REQ_OP_DISCARD &&
1024-
!bdev_max_discard_sectors(bio->bi_bdev))
1025-
disable_discard(md);
1026-
else if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
1027-
!q->limits.max_write_zeroes_sectors)
1028-
disable_write_zeroes(md);
1029-
}
1030-
1031-
if (static_branch_unlikely(&zoned_enabled) &&
1032-
unlikely(blk_queue_is_zoned(q)))
1033-
dm_zone_endio(io, bio);
1019+
if (unlikely(error == BLK_STS_TARGET)) {
1020+
if (bio_op(bio) == REQ_OP_DISCARD &&
1021+
!bdev_max_discard_sectors(bio->bi_bdev))
1022+
disable_discard(md);
1023+
else if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
1024+
!bdev_write_zeroes_sectors(bio->bi_bdev))
1025+
disable_write_zeroes(md);
10341026
}
10351027

1028+
if (static_branch_unlikely(&zoned_enabled) &&
1029+
unlikely(blk_queue_is_zoned(bdev_get_queue(bio->bi_bdev))))
1030+
dm_zone_endio(io, bio);
1031+
10361032
if (endio) {
10371033
int r = endio(ti, bio, &error);
10381034
switch (r) {

0 commit comments

Comments
 (0)