From patchwork Wed May 4 09:39:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 9011841 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 94907BF29F for ; Wed, 4 May 2016 09:42:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B87652038F for ; Wed, 4 May 2016 09:42:57 +0000 (UTC) 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.kernel.org (Postfix) with ESMTPS id 95EED20382 for ; Wed, 4 May 2016 09:42:56 +0000 (UTC) Received: from localhost ([::1]:46641 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1axtKW-0001IT-PR for patchwork-qemu-devel@patchwork.kernel.org; Wed, 04 May 2016 05:42:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39513) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1axtIF-0005cE-Mr for qemu-devel@nongnu.org; Wed, 04 May 2016 05:40:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1axtI3-0005q5-5W for qemu-devel@nongnu.org; Wed, 04 May 2016 05:40:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38306) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1axtHj-0005Xx-4s; Wed, 04 May 2016 05:39:59 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A4E867AE96; Wed, 4 May 2016 09:39:42 +0000 (UTC) Received: from noname.str.redhat.com. (dhcp-192-197.str.redhat.com [10.33.192.197]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u449dYe2000875; Wed, 4 May 2016 05:39:41 -0400 From: Kevin Wolf To: qemu-block@nongnu.org Date: Wed, 4 May 2016 11:39:15 +0200 Message-Id: <1462354765-14037-5-git-send-email-kwolf@redhat.com> In-Reply-To: <1462354765-14037-1-git-send-email-kwolf@redhat.com> References: <1462354765-14037-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 04/14] block: Convert block job core to BlockBackend 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: kwolf@redhat.com, berto@igalia.com, jcody@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This adds a new BlockBackend field to the BlockJob struct, which coexists with the BlockDriverState while converting the individual jobs. When creating a block job, a new BlockBackend is created on top of the given BlockDriverState, and it is destroyed when the BlockJob ends. The reference to the BDS is now held by the BlockBackend instead of calling bdrv_ref/unref manually. We have to be careful when we use bdrv_replace_in_backing_chain() in block jobs because this changes the BDS that job->blk points to. At the moment block jobs are too tightly coupled with their BDS, so that moving a job to another BDS isn't easily possible; therefore, we need to just manually undo this change afterwards. Signed-off-by: Kevin Wolf --- block/mirror.c | 3 +++ blockjob.c | 37 ++++++++++++++++++++----------------- include/block/blockjob.h | 3 ++- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/block/mirror.c b/block/mirror.c index b9986d8..efca8fc 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -478,6 +478,9 @@ static void mirror_exit(BlockJob *job, void *opaque) bdrv_reopen(s->target, bdrv_get_flags(to_replace), NULL); } bdrv_replace_in_backing_chain(to_replace, s->target); + /* We just changed the BDS the job BB refers to */ + blk_remove_bs(job->blk); + blk_insert_bs(job->blk, src); } out: diff --git a/blockjob.c b/blockjob.c index e916b41..01b58c7 100644 --- a/blockjob.c +++ b/blockjob.c @@ -64,13 +64,17 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs, int64_t speed, BlockCompletionFunc *cb, void *opaque, Error **errp) { + BlockBackend *blk; BlockJob *job; if (bs->job) { error_setg(errp, QERR_DEVICE_IN_USE, bdrv_get_device_name(bs)); return NULL; } - bdrv_ref(bs); + + blk = blk_new(&error_abort); + blk_insert_bs(blk, bs); + job = g_malloc0(driver->instance_size); error_setg(&job->blocker, "block device is in use by block job: %s", BlockJobType_lookup[driver->job_type]); @@ -80,6 +84,7 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs, job->driver = driver; job->id = g_strdup(bdrv_get_device_name(bs)); job->bs = bs; + job->blk = blk; job->cb = cb; job->opaque = opaque; job->busy = true; @@ -110,9 +115,10 @@ void block_job_ref(BlockJob *job) void block_job_unref(BlockJob *job) { if (--job->refcnt == 0) { - job->bs->job = NULL; - bdrv_op_unblock_all(job->bs, job->blocker); - bdrv_unref(job->bs); + BlockDriverState *bs = blk_bs(job->blk); + bs->job = NULL; + bdrv_op_unblock_all(bs, job->blocker); + blk_unref(job->blk); error_free(job->blocker); g_free(job->id); QLIST_REMOVE(job, job_list); @@ -153,7 +159,7 @@ static void block_job_completed_txn_abort(BlockJob *job) txn->aborting = true; /* We are the first failed job. Cancel other jobs. */ QLIST_FOREACH(other_job, &txn->jobs, txn_list) { - ctx = bdrv_get_aio_context(other_job->bs); + ctx = blk_get_aio_context(other_job->blk); aio_context_acquire(ctx); } QLIST_FOREACH(other_job, &txn->jobs, txn_list) { @@ -170,7 +176,7 @@ static void block_job_completed_txn_abort(BlockJob *job) assert(other_job->completed); } QLIST_FOREACH_SAFE(other_job, &txn->jobs, txn_list, next) { - ctx = bdrv_get_aio_context(other_job->bs); + ctx = blk_get_aio_context(other_job->blk); block_job_completed_single(other_job); aio_context_release(ctx); } @@ -192,7 +198,7 @@ static void block_job_completed_txn_success(BlockJob *job) } /* We are the last completed job, commit the transaction. */ QLIST_FOREACH_SAFE(other_job, &txn->jobs, txn_list, next) { - ctx = bdrv_get_aio_context(other_job->bs); + ctx = blk_get_aio_context(other_job->blk); aio_context_acquire(ctx); assert(other_job->ret == 0); block_job_completed_single(other_job); @@ -202,9 +208,7 @@ static void block_job_completed_txn_success(BlockJob *job) void block_job_completed(BlockJob *job, int ret) { - BlockDriverState *bs = job->bs; - - assert(bs->job == job); + assert(blk_bs(job->blk)->job == job); assert(!job->completed); job->completed = true; job->ret = ret; @@ -295,11 +299,10 @@ static int block_job_finish_sync(BlockJob *job, void (*finish)(BlockJob *, Error **errp), Error **errp) { - BlockDriverState *bs = job->bs; Error *local_err = NULL; int ret; - assert(bs->job == job); + assert(blk_bs(job->blk)->job == job); block_job_ref(job); finish(job, &local_err); @@ -310,7 +313,7 @@ static int block_job_finish_sync(BlockJob *job, } while (!job->completed) { aio_poll(job->deferred_to_main_loop ? qemu_get_aio_context() : - bdrv_get_aio_context(bs), + blk_get_aio_context(job->blk), true); } ret = (job->cancelled && job->ret == 0) ? -ECANCELED : job->ret; @@ -337,7 +340,7 @@ void block_job_cancel_sync_all(void) AioContext *aio_context; while ((job = QLIST_FIRST(&block_jobs))) { - aio_context = bdrv_get_aio_context(job->bs); + aio_context = blk_get_aio_context(job->blk); aio_context_acquire(aio_context); block_job_cancel_sync(job); aio_context_release(aio_context); @@ -362,7 +365,7 @@ void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns) if (block_job_is_paused(job)) { qemu_coroutine_yield(); } else { - co_aio_sleep_ns(bdrv_get_aio_context(job->bs), type, ns); + co_aio_sleep_ns(blk_get_aio_context(job->blk), type, ns); } job->busy = true; } @@ -491,7 +494,7 @@ static void block_job_defer_to_main_loop_bh(void *opaque) aio_context_acquire(data->aio_context); /* Fetch BDS AioContext again, in case it has changed */ - aio_context = bdrv_get_aio_context(data->job->bs); + aio_context = blk_get_aio_context(data->job->blk); aio_context_acquire(aio_context); data->job->deferred_to_main_loop = false; @@ -511,7 +514,7 @@ void block_job_defer_to_main_loop(BlockJob *job, BlockJobDeferToMainLoopData *data = g_malloc(sizeof(*data)); data->job = job; data->bh = qemu_bh_new(block_job_defer_to_main_loop_bh, data); - data->aio_context = bdrv_get_aio_context(job->bs); + data->aio_context = blk_get_aio_context(job->blk); data->fn = fn; data->opaque = opaque; job->deferred_to_main_loop = true; diff --git a/include/block/blockjob.h b/include/block/blockjob.h index 4ac6831..32012af 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -82,7 +82,8 @@ struct BlockJob { const BlockJobDriver *driver; /** The block device on which the job is operating. */ - BlockDriverState *bs; + BlockDriverState *bs; /* TODO Remove */ + BlockBackend *blk; /** * The ID of the block job. Currently the BlockBackend name of the BDS