Each qio is handled by its own work and process_one_qio() can now
work with qios not requiring metadata. Try to process qios right
after splitting. Insert all leftovers into respective lists for
do_qcow2_work(), keeping the order of the splits.

>From here on process_one_qio() runs in parallel with do_qcow2_work(),
so a write may reach perform_rw_mapped() after main kwork switched
its L2 page from DIRTY to WRITEBACK. perform_rw_mapped() parks such
a write until the writeback ends.

https://virtuozzo.atlassian.net/browse/VSTOR-95494
Feature: dm-qcow2: block device over QCOW2 files driver
Signed-off-by: Andrey Zhadchenko <[email protected]>
---
v2: list_add_tail() keeps the order of deferred splits; commit message
    mentions the race with md writeback; fixed "it's" typo

 drivers/md/dm-qcow2-map.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/md/dm-qcow2-map.c b/drivers/md/dm-qcow2-map.c
index 7d220dd718021..7a8deba4b0a83 100644
--- a/drivers/md/dm-qcow2-map.c
+++ b/drivers/md/dm-qcow2-map.c
@@ -4626,9 +4626,18 @@ static void handle_cleanup_mask(struct qio *qio)
        }
 }
 
+static void qio_try_fast(struct qio *qio, struct list_head *deferred_qios)
+{
+       list_del(&qio->link);
+
+       if (process_one_qio(qio->qcow2, qio, true))
+               list_add_tail(&qio->link, deferred_qios);
+}
+
 static void do_qio_work(struct work_struct *ws)
 {
        struct qio *qio = container_of(ws, struct qio, worker);
+       struct qio *i, *next;
        struct qcow2 *qcow2 = qio->qcow2;
        struct qcow2_target *tgt = qcow2->tgt;
        unsigned int pflags = current->flags;
@@ -4638,8 +4647,12 @@ static void do_qio_work(struct work_struct *ws)
        switch (qio->state) {
        case QIO_STATE_START: {
                LIST_HEAD(deferred_qios);
+               LIST_HEAD(split_qios);
+
+               prepare_one_embedded_qio(qio, &split_qios);
+               list_for_each_entry_safe(i, next, &split_qios, link)
+                       qio_try_fast(i, &deferred_qios);
 
-               prepare_one_embedded_qio(qio, &deferred_qios);
                if (list_empty(&deferred_qios))
                        break;
 
-- 
2.43.5

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to