[RFC PATCH v2 8/8] mirror: protect drains in coroutine with rdlock

Emanuele Giuseppe Esposito posted 8 patches 3 years, 9 months ago
Maintainers: Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>, John Snow <jsnow@redhat.com>, Vladimir Sementsov-Ogievskiy <v.sementsov-og@mail.ru>, Stefan Hajnoczi <stefanha@redhat.com>, Fam Zheng <fam@euphon.net>
[RFC PATCH v2 8/8] mirror: protect drains in coroutine with rdlock
Posted by Emanuele Giuseppe Esposito 3 years, 9 months ago
Drain performed in coroutine schedules a bh in the main loop.
However, drain itself still is a read, and we need to signal
the writer that we are going through the graph.

Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
 block/mirror.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/block/mirror.c b/block/mirror.c
index ce6bc58d1f..de86729f9b 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1065,10 +1065,14 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
             trace_mirror_before_drain(s, cnt);
 
             s->in_drain = true;
+            bdrv_graph_co_rdlock();
             bdrv_drained_begin(bs);
+            bdrv_graph_co_rdunlock();
             cnt = bdrv_get_dirty_count(s->dirty_bitmap);
             if (cnt > 0 || mirror_flush(s) < 0) {
+                bdrv_graph_co_rdlock();
                 bdrv_drained_end(bs);
+                bdrv_graph_co_rdunlock();
                 s->in_drain = false;
                 continue;
             }
@@ -1110,7 +1114,9 @@ immediate_exit:
 
     if (need_drain) {
         s->in_drain = true;
+        bdrv_graph_co_rdlock();
         bdrv_drained_begin(bs);
+        bdrv_graph_co_rdunlock();
     }
 
     return ret;
-- 
2.31.1