From patchwork Tue May 24 13:47:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 9133681 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 2B20C607D3 for ; Tue, 24 May 2016 13:48:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1EB9928258 for ; Tue, 24 May 2016 13:48:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 139FC2828B; Tue, 24 May 2016 13:48:34 +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 ADEE328258 for ; Tue, 24 May 2016 13:48:33 +0000 (UTC) Received: from localhost ([::1]:53470 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5ChE-00026h-M5 for patchwork-qemu-devel@patchwork.kernel.org; Tue, 24 May 2016 09:48:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45895) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5Cgb-00020f-ON for qemu-devel@nongnu.org; Tue, 24 May 2016 09:47:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b5CgZ-0004vl-Me for qemu-devel@nongnu.org; Tue, 24 May 2016 09:47:52 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49881) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5CgW-0004so-5u; Tue, 24 May 2016 09:47:48 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (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 8BEFFC00E8E6; Tue, 24 May 2016 13:47:47 +0000 (UTC) Received: from noname.redhat.com (ovpn-116-43.ams2.redhat.com [10.36.116.43]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u4ODlfTk022386; Tue, 24 May 2016 09:47:45 -0400 From: Kevin Wolf To: qemu-block@nongnu.org Date: Tue, 24 May 2016 15:47:22 +0200 Message-Id: <1464097654-12977-3-git-send-email-kwolf@redhat.com> In-Reply-To: <1464097654-12977-1-git-send-email-kwolf@redhat.com> References: <1464097654-12977-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Tue, 24 May 2016 13:47:47 +0000 (UTC) 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 v2 02/14] block: Cancel jobs first in bdrv_close_all() 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-Virus-Scanned: ClamAV using ClamSMTP So far, bdrv_close_all() first removed all root BlockDriverStates of BlockBackends and monitor owned BDSes, and then assumed that the remaining BDSes must be related to jobs and cancelled these jobs. This order doesn't work that well any more when block jobs use BlockBackends internally because then they will lose their BDS before being cancelled. This patch changes bdrv_close_all() to first cancel all jobs and then remove all root BDSes from the remaining BBs. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake Reviewed-by: Alberto Garcia --- block.c | 23 ++--------------------- blockjob.c | 13 +++++++++++++ include/block/blockjob.h | 7 +++++++ 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/block.c b/block.c index 45cddd6..736432f 100644 --- a/block.c +++ b/block.c @@ -2209,8 +2209,7 @@ static void bdrv_close(BlockDriverState *bs) void bdrv_close_all(void) { - BlockDriverState *bs; - AioContext *aio_context; + block_job_cancel_sync_all(); /* Drop references from requests still in flight, such as canceled block * jobs whose AIO context has not been polled yet */ @@ -2219,25 +2218,7 @@ void bdrv_close_all(void) blk_remove_all_bs(); blockdev_close_all_bdrv_states(); - /* Cancel all block jobs */ - while (!QTAILQ_EMPTY(&all_bdrv_states)) { - QTAILQ_FOREACH(bs, &all_bdrv_states, bs_list) { - aio_context = bdrv_get_aio_context(bs); - - aio_context_acquire(aio_context); - if (bs->job) { - block_job_cancel_sync(bs->job); - aio_context_release(aio_context); - break; - } - aio_context_release(aio_context); - } - - /* All the remaining BlockDriverStates are referenced directly or - * indirectly from block jobs, so there needs to be at least one BDS - * directly used by a block job */ - assert(bs); - } + assert(QTAILQ_EMPTY(&all_bdrv_states)); } static void change_parent_backing_link(BlockDriverState *from, diff --git a/blockjob.c b/blockjob.c index 0f1bc77..e916b41 100644 --- a/blockjob.c +++ b/blockjob.c @@ -331,6 +331,19 @@ int block_job_cancel_sync(BlockJob *job) return block_job_finish_sync(job, &block_job_cancel_err, NULL); } +void block_job_cancel_sync_all(void) +{ + BlockJob *job; + AioContext *aio_context; + + while ((job = QLIST_FIRST(&block_jobs))) { + aio_context = bdrv_get_aio_context(job->bs); + aio_context_acquire(aio_context); + block_job_cancel_sync(job); + aio_context_release(aio_context); + } +} + int block_job_complete_sync(BlockJob *job, Error **errp) { return block_job_finish_sync(job, &block_job_complete, errp); diff --git a/include/block/blockjob.h b/include/block/blockjob.h index 30bb2c6..4ac6831 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -371,6 +371,13 @@ bool block_job_is_paused(BlockJob *job); int block_job_cancel_sync(BlockJob *job); /** + * block_job_cancel_sync_all: + * + * Synchronously cancels all jobs using block_job_cancel_sync(). + */ +void block_job_cancel_sync_all(void); + +/** * block_job_complete_sync: * @job: The job to be completed. * @errp: Error object which may be set by block_job_complete(); this is not