[Devel] [PATCH VZ10 v4 01/11] drivers/md/dm-qcow2: do not attach a bvec to discard qios

Andrey Zhadchenko andrey.zhadchenko at virtuozzo.com
Thu Aug 27 19:06:09 MSK 2026


prepare_one_embedded_qio() skipped bvec setup only for multi-bio
discard requests. A single-bio discard still took the else branch:
payload-less bios have bi_io_vec == NULL and a non-zero bi_size, so
qio->bi_io_vec was set to bio->bi_inline_vecs. That flexible array
is never NULL, but it is not a valid vec list.
Explicitly initialize the qio iterator from the request for every
discard and leave bi_io_vec NULL.

Feature: dm-qcow2: block device over QCOW2 files driver
Fixes: 1118b9c7875a ("dm-qcow2: Introduce driver to create block devices over QCOW2 files")
https://virtuozzo.atlassian.net/browse/VSTOR-139406
Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
---
 drivers/md/dm-qcow2-map.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/md/dm-qcow2-map.c b/drivers/md/dm-qcow2-map.c
index db21efb45e17a..506458f04888e 100644
--- a/drivers/md/dm-qcow2-map.c
+++ b/drivers/md/dm-qcow2-map.c
@@ -3515,6 +3515,14 @@ static struct bio_vec *create_bvec_from_rq(struct request *rq)
 	return bvec;
 }
 
+static void qio_init_iter_from_rq(struct qio *qio, struct request *rq)
+{
+	qio->bi_iter.bi_sector = blk_rq_pos(rq);
+	qio->bi_iter.bi_size = blk_rq_bytes(rq);
+	qio->bi_iter.bi_idx = 0;
+	qio->bi_iter.bi_bvec_done = 0;
+}
+
 static void prepare_one_embedded_qio(struct qcow2 *qcow2, struct qio *qio,
 				     struct list_head *deferred_qios)
 {
@@ -3524,9 +3532,9 @@ static void prepare_one_embedded_qio(struct qcow2 *qcow2, struct qio *qio,
 	LIST_HEAD(list);
 	int ret;
 
-	if (rq->bio != rq->biotail) {
-		if (req_op(rq) == REQ_OP_DISCARD)
-			goto skip_bvec;
+	if (req_op(rq) == REQ_OP_DISCARD) {
+		qio_init_iter_from_rq(qio, rq);
+	} else if (rq->bio != rq->biotail) {
 		/*
 		 * Transform a set of bvec arrays related to bios
 		 * into a single bvec array (which we can iterate).
@@ -3535,11 +3543,7 @@ static void prepare_one_embedded_qio(struct qcow2 *qcow2, struct qio *qio,
 		if (unlikely(!bvec))
 			goto err;
 		qrq->bvec = bvec;
-skip_bvec:
-		qio->bi_iter.bi_sector = blk_rq_pos(rq);
-		qio->bi_iter.bi_size = blk_rq_bytes(rq);
-		qio->bi_iter.bi_idx = 0;
-		qio->bi_iter.bi_bvec_done = 0;
+		qio_init_iter_from_rq(qio, rq);
 	} else {
 		/* Single bio already provides bvec array */
 		bvec = rq->bio->bi_io_vec;
-- 
2.43.5



More information about the Devel mailing list