[Devel] [PATCH RHEL10 COMMIT] drivers/md/dm-qcow2: do not attach a bvec to discard qios

Konstantin Khorenko khorenko at virtuozzo.com
Fri Aug 28 20:03:55 MSK 2026


The commit is pushed to "branch-rh10-6.12.0-211.39.1.16.x.vz10-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git
after rh10-6.12.0-211.39.1.16.11.vz10
------>
commit a3cb7d8331778d9c5601716d419e75906ce2f733
Author: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
Date:   Thu Aug 27 19:06:09 2026 +0300

    drivers/md/dm-qcow2: do not attach a bvec to discard qios
    
    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>
    Reviewed-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
    Reviewed-by: Vasileios Almpanis <vasileios.almpanis at virtuozzo.com>
    Reviewed-by: Konstantin Khorenko <khorenko 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 eaaf0a521d7bd..6ead06ef7b3f9 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;


More information about the Devel mailing list