From patchwork Thu Oct 6 13:02:45 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 9364789 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B037D6075E for ; Thu, 6 Oct 2016 13:23:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A0EF428F81 for ; Thu, 6 Oct 2016 13:23:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9501B28FF0; Thu, 6 Oct 2016 13:23:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7856528F81 for ; Thu, 6 Oct 2016 13:23:48 +0000 (UTC) Received: from localhost ([::1]:56073 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bs8eJ-0006K9-Fu for patchwork-qemu-devel@patchwork.kernel.org; Thu, 06 Oct 2016 09:23:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33250) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bs8Kf-0005jh-UW for qemu-devel@nongnu.org; Thu, 06 Oct 2016 09:03:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bs8Kb-00019V-1Y for qemu-devel@nongnu.org; Thu, 06 Oct 2016 09:03:29 -0400 Received: from smtp3.mundo-r.com ([212.51.32.191]:63651 helo=smtp4.mundo-r.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bs8Ka-00018o-QU; Thu, 06 Oct 2016 09:03:24 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AlAgCgSvZX/5tjdVtdHAEBBAEBCgEBgz0BAQEBAR6BU40ylV0BAQUBgRaPcIIxgg+CC4YgAoF/OBQBAgEBAQEBAQFeJ4RiAgQnUhA/EjwbGYhSAb5hMoVygk+MdgWPLopRj3uPdEmQLR42PwUHghlSHIFWb4hAAQEB X-IPAS-Result: A2AlAgCgSvZX/5tjdVtdHAEBBAEBCgEBgz0BAQEBAR6BU40ylV0BAQUBgRaPcIIxgg+CC4YgAoF/OBQBAgEBAQEBAQFeJ4RiAgQnUhA/EjwbGYhSAb5hMoVygk+MdgWPLopRj3uPdEmQLR42PwUHghlSHIFWb4hAAQEB X-IronPort-AV: E=Sophos;i="5.31,454,1473112800"; d="scan'208";a="195926148" Received: from fanzine.igalia.com ([91.117.99.155]) by smtp4.mundo-r.com with ESMTP; 06 Oct 2016 15:03:19 +0200 Received: from a88-114-146-170.elisa-laajakaista.fi ([88.114.146.170] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim) id 1bs8KV-0001gG-0i; Thu, 06 Oct 2016 15:03:19 +0200 Received: from berto by perseus.local with local (Exim 4.87) (envelope-from ) id 1bs8KH-0007XV-8l; Thu, 06 Oct 2016 16:03:05 +0300 From: Alberto Garcia To: qemu-devel@nongnu.org Date: Thu, 6 Oct 2016 16:02:45 +0300 Message-Id: X-Mailer: git-send-email 2.9.3 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 212.51.32.191 Subject: [Qemu-devel] [PATCH v10 02/16] block: Add block_job_add_bdrv() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-block@nongnu.org, Markus Armbruster , Max Reitz , Stefan Hajnoczi Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP When a block job is created on a certain BlockDriverState, operations are blocked there while the job exists. However, some block jobs may involve additional BDSs, which must be blocked separately when the job is created and unblocked manually afterwards. This patch adds block_job_add_bdrv(), that simplifies this process by keeping a list of BDSs that are involved in the specified block job. Signed-off-by: Alberto Garcia Reviewed-by: Kevin Wolf --- blockjob.c | 19 ++++++++++++++++--- include/block/blockjob.h | 14 ++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/blockjob.c b/blockjob.c index a167f96..b2486a7 100644 --- a/blockjob.c +++ b/blockjob.c @@ -117,6 +117,14 @@ static void block_job_detach_aio_context(void *opaque) block_job_unref(job); } +void block_job_add_bdrv(BlockJob *job, BlockDriverState *bs) +{ + job->nodes = g_slist_prepend(job->nodes, bs); + bdrv_ref(bs); + bdrv_op_block_all(bs, job->blocker); + bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker); +} + void *block_job_create(const char *job_id, const BlockJobDriver *driver, BlockDriverState *bs, int64_t speed, BlockCompletionFunc *cb, void *opaque, Error **errp) @@ -154,8 +162,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, job = g_malloc0(driver->instance_size); error_setg(&job->blocker, "block device is in use by block job: %s", BlockJobType_lookup[driver->job_type]); - bdrv_op_block_all(bs, job->blocker); - bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker); + block_job_add_bdrv(job, bs); job->driver = driver; job->id = g_strdup(job_id); @@ -193,9 +200,15 @@ void block_job_ref(BlockJob *job) void block_job_unref(BlockJob *job) { if (--job->refcnt == 0) { + GSList *l; BlockDriverState *bs = blk_bs(job->blk); bs->job = NULL; - bdrv_op_unblock_all(bs, job->blocker); + for (l = job->nodes; l; l = l->next) { + bs = l->data; + bdrv_op_unblock_all(bs, job->blocker); + bdrv_unref(bs); + } + g_slist_free(job->nodes); blk_remove_aio_context_notifier(job->blk, block_job_attached_aio_context, block_job_detach_aio_context, job); diff --git a/include/block/blockjob.h b/include/block/blockjob.h index 4ddb4ae..c7335f3 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -181,6 +181,9 @@ struct BlockJob { /** Block other operations when block job is running */ Error *blocker; + /** BlockDriverStates that are involved in this block job */ + GSList *nodes; + /** The opaque value that is passed to the completion function. */ void *opaque; @@ -246,6 +249,17 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, BlockCompletionFunc *cb, void *opaque, Error **errp); /** + * block_job_add_bdrv: + * @job: A block job + * @bs: A BlockDriverState that is involved in @job + * + * Add @bs to the list of BlockDriverState that are involved in + * @job. This means that all operations (except dataplane) will be + * blocked on @bs while @job exists. + */ +void block_job_add_bdrv(BlockJob *job, BlockDriverState *bs); + +/** * block_job_sleep_ns: * @job: The job that calls the function. * @clock: The clock to sleep on.