Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

dm: Check for forbidden splitting of zone write operations

DM targets must not split zone append and write operations using
dm_accept_partial_bio() as doing so is forbidden for zone append BIOs,
breaks zone append emulation using regular write BIOs and potentially
creates deadlock situations with queue freeze operations.

Modify dm_accept_partial_bio() to add missing BUG_ON() checks for all
these cases, that is, check that the BIO is a write or write zeroes
operation. This change packs all the zone related checks together under
a static_branch_unlikely(&zoned_enabled) and done only if the target is
a zoned device.

Fixes: f211268ed1f9 ("dm: Use the block layer zone append emulation")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Mikulas Patocka <mpatocka@redhat.com>
Link: https://lore.kernel.org/r/20250625093327.548866-6-dlemoal@kernel.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Damien Le Moal and committed by
Jens Axboe
409f9287 e5496638

+13 -4
+13 -4
drivers/md/dm.c
··· 1293 1293 /* 1294 1294 * A target may call dm_accept_partial_bio only from the map routine. It is 1295 1295 * allowed for all bio types except REQ_PREFLUSH, REQ_OP_ZONE_* zone management 1296 - * operations, REQ_OP_ZONE_APPEND (zone append writes) and any bio serviced by 1297 - * __send_duplicate_bios(). 1296 + * operations, zone append writes (native with REQ_OP_ZONE_APPEND or emulated 1297 + * with write BIOs flagged with BIO_EMULATES_ZONE_APPEND) and any bio serviced 1298 + * by __send_duplicate_bios(). 1298 1299 * 1299 1300 * dm_accept_partial_bio informs the dm that the target only wants to process 1300 1301 * additional n_sectors sectors of the bio and the rest of the data should be ··· 1328 1327 unsigned int bio_sectors = bio_sectors(bio); 1329 1328 1330 1329 BUG_ON(dm_tio_flagged(tio, DM_TIO_IS_DUPLICATE_BIO)); 1331 - BUG_ON(op_is_zone_mgmt(bio_op(bio))); 1332 - BUG_ON(bio_op(bio) == REQ_OP_ZONE_APPEND); 1333 1330 BUG_ON(bio_sectors > *tio->len_ptr); 1334 1331 BUG_ON(n_sectors > bio_sectors); 1332 + 1333 + if (static_branch_unlikely(&zoned_enabled) && 1334 + unlikely(bdev_is_zoned(bio->bi_bdev))) { 1335 + enum req_op op = bio_op(bio); 1336 + 1337 + BUG_ON(op_is_zone_mgmt(op)); 1338 + BUG_ON(op == REQ_OP_WRITE); 1339 + BUG_ON(op == REQ_OP_WRITE_ZEROES); 1340 + BUG_ON(op == REQ_OP_ZONE_APPEND); 1341 + } 1335 1342 1336 1343 *tio->len_ptr -= bio_sectors - n_sectors; 1337 1344 bio->bi_iter.bi_size = n_sectors << SECTOR_SHIFT;