[Devel] [PATCH RHEL9 COMMIT] dm-qcow2: use bio inline vecs in case bi_io_vec is not initiallized

Konstantin Khorenko khorenko at virtuozzo.com
Fri Jul 12 18:20:08 MSK 2024


The commit is pushed to "branch-rh9-5.14.0-427.22.1.vz9.62.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh9-5.14.0-427.22.1.vz9.62.2
------>
commit 4f7a049f70bcb1ab8ca4047f07efa0dafca6c40f
Author: Alexander Atanasov <alexander.atanasov at virtuozzo.com>
Date:   Thu Jul 11 11:16:53 2024 +0300

    dm-qcow2: use bio inline vecs in case bi_io_vec is not initiallized
    
    In some cases bi_io_vec ptr is not initiallized, which can happen after
    bio reset and qcow2 can try to use the ptr before it is reinitiallized
    with bi_inline_vecs.
    
    In that case fallback to use bi_inline_vecs ptr.
    bi_inline_vecs are used when there are less than 4 io vecs.
    
    Add some warnings to trace the problem further if it happens again.
    
    https://virtuozzo.atlassian.net/browse/PSBM-157238
    Signed-off-by: Alexander Atanasov <alexander.atanasov at virtuozzo.com>
    
    khorenko@: so at the moment we don't know why bi_io_vec is left uninitialized,
    and we need those WARN_ONs in order to understand that when we face NULL
    bi_io_vec next time.
    Talking about the hunk which sets detected bi_io_vec to bi_inline_vecs, the
    enhancement is valid and bi_io_vec should be initialized that way, but normally
    it ought to be done at some other place - we'll find the proper place when we
    have reports from newly added WARN_ONs.
    
    Feature: dm-qcow2: debug
---
 drivers/md/dm-qcow2-map.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/md/dm-qcow2-map.c b/drivers/md/dm-qcow2-map.c
index 9cb46fa2cd12..7944e33af8f0 100644
--- a/drivers/md/dm-qcow2-map.c
+++ b/drivers/md/dm-qcow2-map.c
@@ -1246,6 +1246,7 @@ static void __submit_rw_mapped(struct qcow2 *qcow2, struct qio *qio, u32 nr_segs
 
 	rw = (op_is_write(qio->bi_op) ? WRITE : READ);
 	bvec = __bvec_iter_bvec(qio->bi_io_vec, qio->bi_iter);
+	WARN_ON_ONCE(!bvec);
 	pos = to_bytes(qio->bi_iter.bi_sector);
 
 	iov_iter_bvec(&iter, rw, bvec, nr_segs, qio->bi_iter.bi_size);
@@ -3553,7 +3554,15 @@ 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;
-
+		WARN_ON_ONCE(!bvec);
+		if (!bvec) {
+			bvec = rq->bio->bi_inline_vecs;
+			if (unlikely(!bvec)) {
+				QC_ERR(qcow2->tgt->ti, "Expecting inline bvec");
+				WARN_ON_ONCE(1);
+				goto err;
+			}
+		}
 		qio->bi_iter = rq->bio->bi_iter;
 	}
 
@@ -3768,6 +3777,7 @@ static int prepare_sliced_data_write(struct qcow2 *qcow2, struct qio *qio,
 	}
 
 	write_qio->bi_io_vec = qvec->bvec;
+	WARN_ON_ONCE(!write_qio->bi_io_vec);
 	write_qio->bi_iter.bi_idx = 0;
 	write_qio->bi_iter.bi_bvec_done = 0;
 
@@ -4224,6 +4234,7 @@ void qcow2_submit_embedded_qio(struct qcow2_target *tgt, struct qio *qio)
 	qcow2 = qcow2_ref_inc(tgt, &ref_index);
 
 	if (blk_rq_bytes(rq)) {
+		WARN_ON_ONCE(rq->bio && !rq->bio->bi_io_vec);
 		queue_list_id = QLIST_EMBEDDED;
 		worker = &qcow2->worker;
 	} else {


More information about the Devel mailing list