From patchwork Fri Mar 29 13:29:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Shinkevich X-Patchwork-Id: 10877077 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8F85A14DE for ; Fri, 29 Mar 2019 13:32:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7A9D028EA9 for ; Fri, 29 Mar 2019 13:32:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6DFD028E1A; Fri, 29 Mar 2019 13:32:16 +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=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E58AB28E1A for ; Fri, 29 Mar 2019 13:32:15 +0000 (UTC) Received: from localhost ([127.0.0.1]:53018 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9rcF-0003mt-4v for patchwork-qemu-devel@patchwork.kernel.org; Fri, 29 Mar 2019 09:32:15 -0400 Received: from eggs.gnu.org ([209.51.188.92]:47530) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9rZW-0001rs-3Y for qemu-devel@nongnu.org; Fri, 29 Mar 2019 09:29:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h9rZT-0005zP-Vw for qemu-devel@nongnu.org; Fri, 29 Mar 2019 09:29:25 -0400 Received: from relay.sw.ru ([185.231.240.75]:52218) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h9rZT-0005wt-JL; Fri, 29 Mar 2019 09:29:23 -0400 Received: from [172.16.25.136] (helo=localhost.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1h9rZL-0005gf-8Y; Fri, 29 Mar 2019 16:29:15 +0300 From: Andrey Shinkevich To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 29 Mar 2019 16:29:12 +0300 Message-Id: <1553866154-257311-2-git-send-email-andrey.shinkevich@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1553866154-257311-1-git-send-email-andrey.shinkevich@virtuozzo.com> References: <1553866154-257311-1-git-send-email-andrey.shinkevich@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH 1/3] block: include base when checking image chain for block allocation 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, fam@euphon.net, vsementsov@virtuozzo.com, berto@igalia.com, armbru@redhat.com, mreitz@redhat.com, stefanha@redhat.com, andrey.shinkevich@virtuozzo.com, den@openvz.org, 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 A caller of the function bdrv_is_allocated_above() may want to include the base node in the search. It is useful when we have parallel commit/stream jobs on the same backing image chain. The base node may be a top one of a parallel job at the same time and go away before the first job completed. Instead of base, pass the node that has the base as its backing one to the new function bdrv_is_allocated_above_inclusive() to manage the issue. Suggested-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Andrey Shinkevich --- block/io.c | 39 ++++++++++++++++++++++++++++++++++----- include/block/block.h | 5 ++++- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/block/io.c b/block/io.c index dfc153b..8b273e5 100644 --- a/block/io.c +++ b/block/io.c @@ -2317,7 +2317,8 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset, * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP] * * Return true if (a prefix of) the given range is allocated in any image - * between BASE and TOP (inclusive). BASE can be NULL to check if the given + * between BASE and TOP (TOP included). To check the BASE image, set the + * 'base_included' to 'true'. The BASE can be NULL to check if the given * offset is allocated in any image of the chain. Return false otherwise, * or negative errno on failure. * @@ -2329,16 +2330,21 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset, * but 'pnum' will only be 0 when end of file is reached. * */ -int bdrv_is_allocated_above(BlockDriverState *top, - BlockDriverState *base, - int64_t offset, int64_t bytes, int64_t *pnum) +static int bdrv_do_is_allocated_above(BlockDriverState *top, + BlockDriverState *base, + bool base_included, int64_t offset, + int64_t bytes, int64_t *pnum) { BlockDriverState *intermediate; int ret; int64_t n = bytes; + bool exit_loop = top == base ? true : false; + /* Sanity check */ + base_included = base ? base_included : false; + bool include_node = top == base ? base_included : true; intermediate = top; - while (intermediate && intermediate != base) { + while (intermediate && include_node) { int64_t pnum_inter; int64_t size_inter; @@ -2361,12 +2367,35 @@ int bdrv_is_allocated_above(BlockDriverState *top, } intermediate = backing_bs(intermediate); + include_node = intermediate != base; + if (exit_loop) { + include_node = false; + } else if (!include_node && base_included) { + /* Iterate once more */ + include_node = true; + exit_loop = true; + } } *pnum = n; return 0; } +int bdrv_is_allocated_above(BlockDriverState *top, + BlockDriverState *base, + int64_t offset, int64_t bytes, int64_t *pnum) +{ + return bdrv_do_is_allocated_above(top, base, false, offset, bytes, pnum); +} + +int bdrv_is_allocated_above_inclusive(BlockDriverState *top, + BlockDriverState *base, + int64_t offset, int64_t bytes, + int64_t *pnum) +{ + return bdrv_do_is_allocated_above(top, base, true, offset, bytes, pnum); +} + typedef struct BdrvVmstateCo { BlockDriverState *bs; QEMUIOVector *qiov; diff --git a/include/block/block.h b/include/block/block.h index c7a2619..a7846d9 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -448,7 +448,10 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes, int64_t *pnum); int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base, int64_t offset, int64_t bytes, int64_t *pnum); - +int bdrv_is_allocated_above_inclusive(BlockDriverState *top, + BlockDriverState *base, + int64_t offset, int64_t bytes, + int64_t *pnum); bool bdrv_is_read_only(BlockDriverState *bs); int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, bool ignore_allow_rdw, Error **errp);