aboutsummaryrefslogtreecommitdiff
path: root/blockdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'blockdev.c')
-rw-r--r--blockdev.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/blockdev.c b/blockdev.c
index 7bf88d427e..a52f20520d 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -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)