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


Reply via email to