aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFiona Ebner <f.ebner@proxmox.com>2025-05-30 17:10:55 +0200
committerKevin Wolf <kwolf@redhat.com>2025-06-04 18:16:34 +0200
commit195a8a946a8681dfe7e8aa8d49db415693db5311 (patch)
treedb094e990dc939922f8555c690bec30db17c7d6d
parent6f101614f95c889399352b8301917c0ac7919ae7 (diff)
downloadqemu-195a8a946a8681dfe7e8aa8d49db415693db5311.zip
qemu-195a8a946a8681dfe7e8aa8d49db415693db5311.tar.gz
qemu-195a8a946a8681dfe7e8aa8d49db415693db5311.tar.bz2
blockdev: drain while unlocked in external_snapshot_action()
This is in preparation to mark bdrv_drained_begin() as GRAPH_UNLOCKED. Signed-off-by: Fiona Ebner <f.ebner@proxmox.com> Message-ID: <20250530151125.955508-19-f.ebner@proxmox.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r--blockdev.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/blockdev.c b/blockdev.c
index 506755b..2e7fda6 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1377,9 +1377,10 @@ static void external_snapshot_action(TransactionAction *action,
const char *new_image_file;
ExternalSnapshotState *state = g_new0(ExternalSnapshotState, 1);
uint64_t perm, shared;
+ BlockDriverState *check_bs;
/* TODO We'll eventually have to take a writer lock in this function */
- GRAPH_RDLOCK_GUARD_MAINLOOP();
+ bdrv_graph_rdlock_main_loop();
tran_add(tran, &external_snapshot_drv, state);
@@ -1412,11 +1413,25 @@ static void external_snapshot_action(TransactionAction *action,
state->old_bs = bdrv_lookup_bs(device, node_name, errp);
if (!state->old_bs) {
+ bdrv_graph_rdunlock_main_loop();
return;
}
+ /* Need to drain while unlocked. */
+ bdrv_graph_rdunlock_main_loop();
/* Paired with .clean() */
bdrv_drained_begin(state->old_bs);
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ /* Make sure the associated bs did not change with the drain. */
+ check_bs = bdrv_lookup_bs(device, node_name, errp);
+ if (state->old_bs != check_bs) {
+ if (check_bs) {
+ error_setg(errp, "Block node of device '%s' unexpectedly changed",
+ device);
+ } /* else errp is already set */
+ return;
+ }
if (!bdrv_is_inserted(state->old_bs)) {
error_setg(errp, "Device '%s' has no medium",