[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH for-2.3 4/4] blockdev: acquire AioContext in change-
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PATCH for-2.3 4/4] blockdev: acquire AioContext in change-backing-file |
Date: |
Wed, 19 Nov 2014 14:19:45 +0000 |
Add dataplane support to the change-backing-file QMP commands. By
acquiring the AioContext we avoid race conditions with the dataplane
thread which may also be accessing the BlockDriverState.
Note that this command operates on both bs and a node in its chain
(image_bs). The bdrv_chain_contains(bs, image_bs) check guarantees that
bs and image_bs are in the same AioContext.
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
blockdev.c | 19 +++++++++++++------
hw/block/dataplane/virtio-blk.c | 1 +
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index 7bf88d4..a52f205 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)
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,
--
2.1.0
- [Qemu-devel] [PATCH for-2.3 0/4] blockdev: support dataplane in remaining QMP commands, Stefan Hajnoczi, 2014/11/19
- [Qemu-devel] [PATCH for-2.3 1/4] blockdev: acquire AioContext in blockdev-snapshot-delete-internal-sync, Stefan Hajnoczi, 2014/11/19
- [Qemu-devel] [PATCH for-2.3 2/4] blockdev: check for BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE, Stefan Hajnoczi, 2014/11/19
- [Qemu-devel] [PATCH for-2.3 3/4] blockdev: acquire AioContext in eject, change, and block_passwd, Stefan Hajnoczi, 2014/11/19
- [Qemu-devel] [PATCH for-2.3 4/4] blockdev: acquire AioContext in change-backing-file,
Stefan Hajnoczi <=
- Re: [Qemu-devel] [PATCH for-2.3 0/4] blockdev: support dataplane in remaining QMP commands, Max Reitz, 2014/11/20