In some cases qcow2 is passed requests without bvec set and zero bi_size - for such requests qcow2 resorts to inline bvecs which in that case are invalid.
To address this: - Check if bi_size is not zero, and only then use the inline bvecs. - Properly count number of segments in a NULL bvec. - Add warn on to catch if we have a requests without bvec and bi_size. https://virtuozzo.atlassian.net/browse/PSBM-159903 Signed-off-by: Alexander Atanasov <alexander.atana...@virtuozzo.com> --- drivers/md/dm-qcow2-map.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/md/dm-qcow2-map.c b/drivers/md/dm-qcow2-map.c index 6585f3fac6e7..a28f6332dc08 100644 --- a/drivers/md/dm-qcow2-map.c +++ b/drivers/md/dm-qcow2-map.c @@ -308,6 +308,9 @@ static unsigned int qio_nr_segs(struct qio *qio) struct bvec_iter iter; struct bio_vec bv; + if (!qio->bi_io_vec) + return nr_segs; + qcow2_for_each_bvec(iter, bv, qio->bi_iter, qio->bi_io_vec) nr_segs++; @@ -1248,6 +1251,7 @@ static void __submit_rw_mapped(struct qcow2 *qcow2, struct qio *qio, u32 nr_segs bvec = __bvec_iter_bvec(qio->bi_io_vec, qio->bi_iter); pos = to_bytes(qio->bi_iter.bi_sector); + WARN_ON(qio->bi_iter.bi_size && !bvec); iov_iter_bvec(&iter, rw, bvec, nr_segs, qio->bi_iter.bi_size); iter.iov_offset = qio->bi_iter.bi_bvec_done; @@ -3538,7 +3542,7 @@ static void prepare_one_embedded_qio(struct qcow2 *qcow2, struct qio *qio, } else { /* Single bio already provides bvec array */ bvec = rq->bio->bi_io_vec; - if (!bvec) { + if (!bvec && rq->bio->bi_iter.bi_size) { bvec = rq->bio->bi_inline_vecs; if (unlikely(!bvec)) { QC_ERR(qcow2->tgt->ti, "Expecting inline bvec"); -- 2.43.0 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel