summaryrefslogtreecommitdiff
path: root/block.c
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2014-05-08 16:34:35 +0200
committerStefan Hajnoczi <stefanha@redhat.com>2014-06-04 09:56:11 +0200
commited78cda3de92056737364ab3cb748b16f5f17dea (patch)
treec9b373510c8aa9741f3d7db8dc08a74b88b0e8ba /block.c
parent2572b37a4751cc967582d7d04f21d9bf97187ae5 (diff)
downloadqemu-ed78cda3de92056737364ab3cb748b16f5f17dea.tar.gz
block: acquire AioContext in bdrv_*_all()
bdrv_close_all(), bdrv_commit_all(), bdrv_flush_all(), bdrv_invalidate_cache_all(), and bdrv_clear_incoming_migration_all() are called by main loop code and touch all BlockDriverState instances. Some BlockDriverState instances may be running in another AioContext. Make sure to acquire the AioContext before closing the BlockDriverState. This will protect against race conditions once virtio-blk data-plane is using the BlockDriverState from another AioContext event loop. Note that this patch does not convert bdrv_drain_all() yet since that conversion is non-trivial. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'block.c')
-rw-r--r--block.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/block.c b/block.c
index 05ec8e13e4..7cccb84dab 100644
--- a/block.c
+++ b/block.c
@@ -1856,7 +1856,11 @@ void bdrv_close_all(void)
BlockDriverState *bs;
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
+ AioContext *aio_context = bdrv_get_aio_context(bs);
+
+ aio_context_acquire(aio_context);
bdrv_close(bs);
+ aio_context_release(aio_context);
}
}
@@ -2352,12 +2356,17 @@ int bdrv_commit_all(void)
BlockDriverState *bs;
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
+ AioContext *aio_context = bdrv_get_aio_context(bs);
+
+ aio_context_acquire(aio_context);
if (bs->drv && bs->backing_hd) {
int ret = bdrv_commit(bs);
if (ret < 0) {
+ aio_context_release(aio_context);
return ret;
}
}
+ aio_context_release(aio_context);
}
return 0;
}
@@ -3833,10 +3842,15 @@ int bdrv_flush_all(void)
int result = 0;
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
- int ret = bdrv_flush(bs);
+ AioContext *aio_context = bdrv_get_aio_context(bs);
+ int ret;
+
+ aio_context_acquire(aio_context);
+ ret = bdrv_flush(bs);
if (ret < 0 && !result) {
result = ret;
}
+ aio_context_release(aio_context);
}
return result;
@@ -4982,7 +4996,11 @@ void bdrv_invalidate_cache_all(Error **errp)
Error *local_err = NULL;
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
+ AioContext *aio_context = bdrv_get_aio_context(bs);
+
+ aio_context_acquire(aio_context);
bdrv_invalidate_cache(bs, &local_err);
+ aio_context_release(aio_context);
if (local_err) {
error_propagate(errp, local_err);
return;
@@ -4995,7 +5013,11 @@ void bdrv_clear_incoming_migration_all(void)
BlockDriverState *bs;
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
+ AioContext *aio_context = bdrv_get_aio_context(bs);
+
+ aio_context_acquire(aio_context);
bs->open_flags = bs->open_flags & ~(BDRV_O_INCOMING);
+ aio_context_release(aio_context);
}
}