[Devel] [PATCH VZ10 v3 01/11] drivers/md/dm-qcow2: do not attach a bvec to discard qios
Andrey Zhadchenko
andrey.zhadchenko at virtuozzo.com
Tue Aug 25 15:24:20 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