From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49541) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5cnX-0005vL-7a for qemu-devel@nongnu.org; Wed, 25 May 2016 13:40:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b5cnW-0004aL-1k for qemu-devel@nongnu.org; Wed, 25 May 2016 13:40:47 -0400 From: Kevin Wolf Date: Wed, 25 May 2016 19:39:37 +0200 Message-Id: <1464197996-4581-13-git-send-email-kwolf@redhat.com> In-Reply-To: <1464197996-4581-1-git-send-email-kwolf@redhat.com> References: <1464197996-4581-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PULL 12/31] block: Make bdrv_drain() use bdrv_drained_begin/end() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: kwolf@redhat.com, qemu-devel@nongnu.org Until now, bdrv_drained_begin() used bdrv_drain() internally to drain the queue. This is kind of backwards and caused quiescing code to be duplicated because bdrv_drained_begin() had to ensure that no new requests come in even after bdrv_drain() returns, whereas bdrv_drain() had to have them because it could be called from other places. Instead move the bdrv_drain() code to bdrv_drained_begin() and make bdrv_drain() a simple wrapper around bdrv_drained_begin/end(). Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake Reviewed-by: Fam Zheng --- block/io.c | 69 ++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/block/io.c b/block/io.c index 2a28d63..9bc1d45 100644 --- a/block/io.c +++ b/block/io.c @@ -225,6 +225,34 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs) assert(data.done); } +void bdrv_drained_begin(BlockDriverState *bs) +{ + if (!bs->quiesce_counter++) { + aio_disable_external(bdrv_get_aio_context(bs)); + bdrv_parent_drained_begin(bs); + } + + bdrv_io_unplugged_begin(bs); + bdrv_drain_recurse(bs); + if (qemu_in_coroutine()) { + bdrv_co_yield_to_drain(bs); + } else { + bdrv_drain_poll(bs); + } + bdrv_io_unplugged_end(bs); +} + +void bdrv_drained_end(BlockDriverState *bs) +{ + assert(bs->quiesce_counter > 0); + if (--bs->quiesce_counter > 0) { + return; + } + + bdrv_parent_drained_end(bs); + aio_enable_external(bdrv_get_aio_context(bs)); +} + /* * Wait for pending requests to complete on a single BlockDriverState subtree, * and suspend block driver's internal I/O until next request arrives. @@ -238,26 +266,15 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs) */ void coroutine_fn bdrv_co_drain(BlockDriverState *bs) { - bdrv_parent_drained_begin(bs); - bdrv_io_unplugged_begin(bs); - bdrv_drain_recurse(bs); - bdrv_co_yield_to_drain(bs); - bdrv_io_unplugged_end(bs); - bdrv_parent_drained_end(bs); + assert(qemu_in_coroutine()); + bdrv_drained_begin(bs); + bdrv_drained_end(bs); } void bdrv_drain(BlockDriverState *bs) { - bdrv_parent_drained_begin(bs); - bdrv_io_unplugged_begin(bs); - bdrv_drain_recurse(bs); - if (qemu_in_coroutine()) { - bdrv_co_yield_to_drain(bs); - } else { - bdrv_drain_poll(bs); - } - bdrv_io_unplugged_end(bs); - bdrv_parent_drained_end(bs); + bdrv_drained_begin(bs); + bdrv_drained_end(bs); } /* @@ -2541,23 +2558,3 @@ void bdrv_io_unplugged_end(BlockDriverState *bs) } } } - -void bdrv_drained_begin(BlockDriverState *bs) -{ - if (!bs->quiesce_counter++) { - aio_disable_external(bdrv_get_aio_context(bs)); - } - bdrv_parent_drained_begin(bs); - bdrv_drain(bs); -} - -void bdrv_drained_end(BlockDriverState *bs) -{ - bdrv_parent_drained_end(bs); - - assert(bs->quiesce_counter > 0); - if (--bs->quiesce_counter > 0) { - return; - } - aio_enable_external(bdrv_get_aio_context(bs)); -} -- 1.8.3.1