diff options
author | Fiona Ebner <f.ebner@proxmox.com> | 2025-05-30 17:10:55 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2025-06-04 18:16:34 +0200 |
commit | 195a8a946a8681dfe7e8aa8d49db415693db5311 (patch) | |
tree | db094e990dc939922f8555c690bec30db17c7d6d | |
parent | 6f101614f95c889399352b8301917c0ac7919ae7 (diff) | |
download | qemu-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.c | 17 |
1 files changed, 16 insertions, 1 deletions
@@ -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", |