From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrey Zhadchenko Date: Tue, 25 Aug 2026 15:24:20 +0300 Subject: [Devel] [PATCH VZ10 v3 01/11] drivers/md/dm-qcow2: do not attach a bvec to discard qios In-Reply-To: <20260825122430.252094-1-andrey.zhadchenko@virtuozzo.com> References: <20260825122430.252094-1-andrey.zhadchenko@virtuozzo.com> Message-ID: <20260825122430.252094-2-andrey.zhadchenko@virtuozzo.com> List-Id: 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 --- 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