diff options
-rw-r--r-- | blockdev.c | 19 | ||||
-rw-r--r-- | hw/block/dataplane/virtio-blk.c | 1 |
2 files changed, 14 insertions, 6 deletions
@@ -2584,6 +2584,7 @@ void qmp_change_backing_file(const char *device, Error **errp) { BlockDriverState *bs = NULL; + AioContext *aio_context; BlockDriverState *image_bs = NULL; Error *local_err = NULL; bool ro; @@ -2597,34 +2598,37 @@ void qmp_change_backing_file(const char *device, return; } + aio_context = bdrv_get_aio_context(bs); + aio_context_acquire(aio_context); + image_bs = bdrv_lookup_bs(NULL, image_node_name, &local_err); if (local_err) { error_propagate(errp, local_err); - return; + goto out; } if (!image_bs) { error_setg(errp, "image file not found"); - return; + goto out; } if (bdrv_find_base(image_bs) == image_bs) { error_setg(errp, "not allowing backing file change on an image " "without a backing file"); - return; + goto out; } /* even though we are not necessarily operating on bs, we need it to * determine if block ops are currently prohibited on the chain */ if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_CHANGE, errp)) { - return; + goto out; } /* final sanity check */ if (!bdrv_chain_contains(bs, image_bs)) { error_setg(errp, "'%s' and image file are not in the same chain", device); - return; + goto out; } /* if not r/w, reopen to make r/w */ @@ -2635,7 +2639,7 @@ void qmp_change_backing_file(const char *device, bdrv_reopen(image_bs, open_flags | BDRV_O_RDWR, &local_err); if (local_err) { error_propagate(errp, local_err); - return; + goto out; } } @@ -2655,6 +2659,9 @@ void qmp_change_backing_file(const char *device, error_propagate(errp, local_err); /* will preserve prior errp */ } } + +out: + aio_context_release(aio_context); } void qmp_blockdev_add(BlockdevOptions *options, Error **errp) diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index 2548113..90ab27e 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -197,6 +197,7 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_RESIZE, s->blocker); blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker); blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_BACKUP_SOURCE, s->blocker); + blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_CHANGE, s->blocker); blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_COMMIT, s->blocker); blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_EJECT, s->blocker); blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE, |