From f3e69beb942103ccd5248273e4d95e76b64ab64c Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Tue, 21 Oct 2014 12:03:57 +0100 Subject: block: let stream blockjob run in BDS AioContext The stream block job must run in the BlockDriverState AioContext so that it works with dataplane. The basics of acquiring the AioContext are easy in blockdev.c. The tricky part is the completion code which drops part of the backing file chain. This must be done in the main loop where bdrv_unref() and bdrv_close() are safe to call. Use block_job_defer_to_main_loop() to achieve that. Signed-off-by: Stefan Hajnoczi Reviewed-by: Max Reitz Message-id: 1413889440-32577-9-git-send-email-stefanha@redhat.com --- blockdev.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'blockdev.c') diff --git a/blockdev.c b/blockdev.c index 9c6898833b..6e43d2e3a8 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1963,6 +1963,7 @@ void qmp_block_stream(const char *device, { BlockDriverState *bs; BlockDriverState *base_bs = NULL; + AioContext *aio_context; Error *local_err = NULL; const char *base_name = NULL; @@ -1976,16 +1977,20 @@ void qmp_block_stream(const char *device, return; } + aio_context = bdrv_get_aio_context(bs); + aio_context_acquire(aio_context); + if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_STREAM, errp)) { - return; + goto out; } if (has_base) { base_bs = bdrv_find_backing_image(bs, base); if (base_bs == NULL) { error_set(errp, QERR_BASE_NOT_FOUND, base); - return; + goto out; } + assert(bdrv_get_aio_context(base_bs) == aio_context); base_name = base; } @@ -1994,7 +1999,7 @@ void qmp_block_stream(const char *device, if (base_bs == NULL && has_backing_file) { error_setg(errp, "backing file specified, but streaming the " "entire chain"); - return; + goto out; } /* backing_file string overrides base bs filename */ @@ -2004,10 +2009,13 @@ void qmp_block_stream(const char *device, on_error, block_job_cb, bs, &local_err); if (local_err) { error_propagate(errp, local_err); - return; + goto out; } trace_qmp_block_stream(bs, bs->job); + +out: + aio_context_release(aio_context); } void qmp_block_commit(const char *device, -- cgit v1.2.1