diff options
author | Fiona Ebner <f.ebner@proxmox.com> | 2025-05-30 17:10:54 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2025-06-04 18:16:34 +0200 |
commit | 6f101614f95c889399352b8301917c0ac7919ae7 (patch) | |
tree | 2585d66797c910c0ad2753fd8426e7cd71149451 | |
parent | d75f8ed1d7fc27cf1643e549cd006a68d3bf6ef1 (diff) | |
download | qemu-6f101614f95c889399352b8301917c0ac7919ae7.zip qemu-6f101614f95c889399352b8301917c0ac7919ae7.tar.gz qemu-6f101614f95c889399352b8301917c0ac7919ae7.tar.bz2 |
blockdev: drain while unlocked in internal_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-18-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r-- | blockdev.c | 19 |
1 files changed, 17 insertions, 2 deletions
@@ -1208,7 +1208,7 @@ static void internal_snapshot_action(BlockdevSnapshotInternal *internal, Error *local_err = NULL; const char *device; const char *name; - BlockDriverState *bs; + BlockDriverState *bs, *check_bs; QEMUSnapshotInfo old_sn, *sn; bool ret; int64_t rt; @@ -1216,7 +1216,7 @@ static void internal_snapshot_action(BlockdevSnapshotInternal *internal, int ret1; GLOBAL_STATE_CODE(); - GRAPH_RDLOCK_GUARD_MAINLOOP(); + bdrv_graph_rdlock_main_loop(); tran_add(tran, &internal_snapshot_drv, state); @@ -1225,14 +1225,29 @@ static void internal_snapshot_action(BlockdevSnapshotInternal *internal, bs = qmp_get_root_bs(device, errp); if (!bs) { + bdrv_graph_rdunlock_main_loop(); return; } state->bs = bs; + /* Need to drain while unlocked. */ + bdrv_graph_rdunlock_main_loop(); /* Paired with .clean() */ bdrv_drained_begin(bs); + GRAPH_RDLOCK_GUARD_MAINLOOP(); + + /* Make sure the root bs did not change with the drain. */ + check_bs = qmp_get_root_bs(device, errp); + if (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_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) { return; } |