From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34482) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XZNIA-0002X9-Q1 for qemu-devel@nongnu.org; Wed, 01 Oct 2014 13:02:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XZNI1-0001ZU-7J for qemu-devel@nongnu.org; Wed, 01 Oct 2014 13:02:18 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44508) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XZNI1-0001ZL-0s for qemu-devel@nongnu.org; Wed, 01 Oct 2014 13:02:09 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s91H28xZ012408 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 1 Oct 2014 13:02:08 -0400 From: Stefan Hajnoczi Date: Wed, 1 Oct 2014 18:01:49 +0100 Message-Id: <1412182919-9550-2-git-send-email-stefanha@redhat.com> In-Reply-To: <1412182919-9550-1-git-send-email-stefanha@redhat.com> References: <1412182919-9550-1-git-send-email-stefanha@redhat.com> Subject: [Qemu-devel] [PATCH 01/11] block: acquire AioContext in generic blockjob QMP commands List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Paolo Bonzini , Fam Zheng , Stefan Hajnoczi , Max Reitz block-job-set-speed, block-job-cancel, block-job-pause, block-job-resume, and block-job-complete must acquire the BlockDriverState AioContext so that it is safe to access bs. At the moment bs->job is always NULL when dataplane is active because op blockers prevent blockjobs from starting. Once the rest of the blockjob API has been made aware of AioContext we can drop the op blocker. Signed-off-by: Stefan Hajnoczi --- blockdev.c | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/blockdev.c b/blockdev.c index ad43648..379a268 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2335,20 +2335,35 @@ void qmp_drive_mirror(const char *device, const char *target, } } -static BlockJob *find_block_job(const char *device) +/* Get the block job for a given device name and acquire its AioContext */ +static BlockJob *find_block_job(const char *device, AioContext **aio_context) { BlockDriverState *bs; bs = bdrv_find(device); - if (!bs || !bs->job) { - return NULL; + if (!bs) { + goto notfound; + } + + *aio_context = bdrv_get_aio_context(bs); + aio_context_acquire(*aio_context); + + if (!bs->job) { + aio_context_release(*aio_context); + goto notfound; } + return bs->job; + +notfound: + *aio_context = NULL; + return NULL; } void qmp_block_job_set_speed(const char *device, int64_t speed, Error **errp) { - BlockJob *job = find_block_job(device); + AioContext *aio_context; + BlockJob *job = find_block_job(device, &aio_context); if (!job) { error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device); @@ -2356,34 +2371,40 @@ void qmp_block_job_set_speed(const char *device, int64_t speed, Error **errp) } block_job_set_speed(job, speed, errp); + aio_context_release(aio_context); } void qmp_block_job_cancel(const char *device, bool has_force, bool force, Error **errp) { - BlockJob *job = find_block_job(device); - - if (!has_force) { - force = false; - } + AioContext *aio_context; + BlockJob *job = find_block_job(device, &aio_context); if (!job) { error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device); return; } + + if (!has_force) { + force = false; + } + if (job->paused && !force) { error_setg(errp, "The block job for device '%s' is currently paused", device); - return; + goto out; } trace_qmp_block_job_cancel(job); block_job_cancel(job); +out: + aio_context_release(aio_context); } void qmp_block_job_pause(const char *device, Error **errp) { - BlockJob *job = find_block_job(device); + AioContext *aio_context; + BlockJob *job = find_block_job(device, &aio_context); if (!job) { error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device); @@ -2392,11 +2413,13 @@ void qmp_block_job_pause(const char *device, Error **errp) trace_qmp_block_job_pause(job); block_job_pause(job); + aio_context_release(aio_context); } void qmp_block_job_resume(const char *device, Error **errp) { - BlockJob *job = find_block_job(device); + AioContext *aio_context; + BlockJob *job = find_block_job(device, &aio_context); if (!job) { error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device); @@ -2405,11 +2428,13 @@ void qmp_block_job_resume(const char *device, Error **errp) trace_qmp_block_job_resume(job); block_job_resume(job); + aio_context_release(aio_context); } void qmp_block_job_complete(const char *device, Error **errp) { - BlockJob *job = find_block_job(device); + AioContext *aio_context; + BlockJob *job = find_block_job(device, &aio_context); if (!job) { error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device); @@ -2418,6 +2443,7 @@ void qmp_block_job_complete(const char *device, Error **errp) trace_qmp_block_job_complete(job); block_job_complete(job, errp); + aio_context_release(aio_context); } void qmp_change_backing_file(const char *device, -- 1.9.3