This adds GRAPH_RDLOCK annotations to declare that callers of
bdrv_register_buf() and bdrv_unregister_buf() need to hold a reader lock
for the graph.

Signed-off-by: Kevin Wolf <kw...@redhat.com>
Message-Id: <20230203152202.49054-21-kw...@redhat.com>
Reviewed-by: Emanuele Giuseppe Esposito <eespo...@redhat.com>
Signed-off-by: Kevin Wolf <kw...@redhat.com>
---
 include/block/block_int-common.h |  7 ++++---
 block/io.c                       | 14 ++++++++++----
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index 30e6bd4909..88d9897c97 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -445,9 +445,10 @@ struct BlockDriver {
      *
      * Returns: true on success, false on failure
      */
-    bool (*bdrv_register_buf)(BlockDriverState *bs, void *host, size_t size,
-                              Error **errp);
-    void (*bdrv_unregister_buf)(BlockDriverState *bs, void *host, size_t size);
+    bool GRAPH_RDLOCK_PTR (*bdrv_register_buf)(
+        BlockDriverState *bs, void *host, size_t size, Error **errp);
+    void GRAPH_RDLOCK_PTR (*bdrv_unregister_buf)(
+        BlockDriverState *bs, void *host, size_t size);
 
     /*
      * This field is modified only under the BQL, and is part of
diff --git a/block/io.c b/block/io.c
index b5459c2f41..8974d46941 100644
--- a/block/io.c
+++ b/block/io.c
@@ -3187,13 +3187,15 @@ void coroutine_fn bdrv_co_io_unplug(BlockDriverState 
*bs)
 }
 
 /* Helper that undoes bdrv_register_buf() when it fails partway through */
-static void bdrv_register_buf_rollback(BlockDriverState *bs,
-                                       void *host,
-                                       size_t size,
-                                       BdrvChild *final_child)
+static void GRAPH_RDLOCK
+bdrv_register_buf_rollback(BlockDriverState *bs, void *host, size_t size,
+                           BdrvChild *final_child)
 {
     BdrvChild *child;
 
+    GLOBAL_STATE_CODE();
+    assert_bdrv_graph_readable();
+
     QLIST_FOREACH(child, &bs->children, next) {
         if (child == final_child) {
             break;
@@ -3213,6 +3215,8 @@ bool bdrv_register_buf(BlockDriverState *bs, void *host, 
size_t size,
     BdrvChild *child;
 
     GLOBAL_STATE_CODE();
+    GRAPH_RDLOCK_GUARD_MAINLOOP();
+
     if (bs->drv && bs->drv->bdrv_register_buf) {
         if (!bs->drv->bdrv_register_buf(bs, host, size, errp)) {
             return false;
@@ -3232,6 +3236,8 @@ void bdrv_unregister_buf(BlockDriverState *bs, void 
*host, size_t size)
     BdrvChild *child;
 
     GLOBAL_STATE_CODE();
+    GRAPH_RDLOCK_GUARD_MAINLOOP();
+
     if (bs->drv && bs->drv->bdrv_unregister_buf) {
         bs->drv->bdrv_unregister_buf(bs, host, size);
     }
-- 
2.39.2


Reply via email to