When a DM target does not support native zone append, the block layer zone write plugging will transform a REQ_OP_ZONE_APPEND operation into a regular REQ_OP_WRITE BIO flagged with BIO_EMULATES_ZONE_APPEND. A DM target must always be able to process such write request without resorting to calling dm_accept_partial_bio() as otherwise, the original BIO cannot indicate to the issuer a correct written sector on completion. Make sure that dm_accept_partial_bio() is never called for an emulated zone append BIO with a BUG_ON() check in dm_accept_partial_bio().
Signed-off-by: Damien Le Moal <dlem...@kernel.org> --- drivers/md/dm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 55579adbeb3f..21920991ab28 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1286,8 +1286,9 @@ static size_t dm_dax_recovery_write(struct dax_device *dax_dev, pgoff_t pgoff, /* * A target may call dm_accept_partial_bio only from the map routine. It is * allowed for all bio types except REQ_PREFLUSH, REQ_OP_ZONE_* zone management - * operations, REQ_OP_ZONE_APPEND (zone append writes) and any bio serviced by - * __send_duplicate_bios(). + * operations, zone append writes (native with REQ_OP_ZONE_APPEND or emulated + * with write BIOs flagged with BIO_EMULATES_ZONE_APPEND) and any bio serviced + * by __send_duplicate_bios(). * * dm_accept_partial_bio informs the dm that the target only wants to process * additional n_sectors sectors of the bio and the rest of the data should be @@ -1322,6 +1323,7 @@ void dm_accept_partial_bio(struct bio *bio, unsigned int n_sectors) BUG_ON(dm_tio_flagged(tio, DM_TIO_IS_DUPLICATE_BIO)); BUG_ON(op_is_zone_mgmt(bio_op(bio))); BUG_ON(bio_op(bio) == REQ_OP_ZONE_APPEND); + BUG_ON(bio_flagged(bio, BIO_EMULATES_ZONE_APPEND)); BUG_ON(bio_sectors > *tio->len_ptr); BUG_ON(n_sectors > bio_sectors); -- 2.49.0