block: Mark bdrv_root_unref_child() GRAPH_WRLOCK
Instead of taking the writer lock internally, require callers to already
hold it when calling bdrv_root_unref_child(). These callers will
typically already hold the graph lock once the locking work is
completed, which means that they can't call functions that take it
internally.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20230911094620.45040-20-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
diff --git a/block.c b/block.c
index 8e589bb..9ea8333 100644
--- a/block.c
+++ b/block.c
@@ -3268,7 +3268,6 @@
BlockDriverState *child_bs = child->bs;
GLOBAL_STATE_CODE();
- bdrv_graph_wrlock(NULL);
bdrv_replace_child_noperm(child, NULL);
bdrv_child_free(child);
@@ -3288,8 +3287,7 @@
NULL);
}
- bdrv_graph_wrunlock();
- bdrv_unref(child_bs);
+ bdrv_schedule_unref(child_bs);
}
typedef struct BdrvSetInheritsFrom {
@@ -3366,8 +3364,10 @@
return;
}
+ bdrv_graph_wrlock(NULL);
bdrv_unset_inherits_from(parent, child, NULL);
bdrv_root_unref_child(child);
+ bdrv_graph_wrunlock();
}