From patchwork Fri Aug 9 16:13:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087013 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 6FC0F1709 for ; Fri, 9 Aug 2019 16:15:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5DC4F1FF28 for ; Fri, 9 Aug 2019 16:15:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 51B721FF87; Fri, 9 Aug 2019 16:15:04 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E7634201B0 for ; Fri, 9 Aug 2019 16:15:02 +0000 (UTC) Received: from localhost ([::1]:60784 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Xh-0002D9-Op for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:15:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56678) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7X3-0000JZ-1j for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7X0-0003s4-Pa for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:20 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56216) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Wv-0003oh-2f; Fri, 09 Aug 2019 12:14:13 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D0D86C04574F; Fri, 9 Aug 2019 16:14:11 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6DE16608C2; Fri, 9 Aug 2019 16:14:11 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:26 +0200 Message-Id: <20190809161407.11920-2-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 09 Aug 2019 16:14:11 +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 v6 01/42] block: Mark commit and mirror as filter drivers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP The commit and mirror block nodes are filters, so they should be marked as such. (Strictly speaking, BDS.is_filter's documentation states that a filter's child must be bs->file. The following patch will relax this restriction, however.) Signed-off-by: Max Reitz Reviewed-by: Alberto Garcia Reviewed-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/commit.c | 2 ++ block/mirror.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/block/commit.c b/block/commit.c index 408ae15389..19915603ae 100644 --- a/block/commit.c +++ b/block/commit.c @@ -254,6 +254,8 @@ static BlockDriver bdrv_commit_top = { .bdrv_co_block_status = bdrv_co_block_status_from_backing, .bdrv_refresh_filename = bdrv_commit_top_refresh_filename, .bdrv_child_perm = bdrv_commit_top_child_perm, + + .is_filter = true, }; void commit_start(const char *job_id, BlockDriverState *bs, diff --git a/block/mirror.c b/block/mirror.c index 2b870683f1..a8f2d7a305 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -1507,6 +1507,8 @@ static BlockDriver bdrv_mirror_top = { .bdrv_refresh_filename = bdrv_mirror_top_refresh_filename, .bdrv_child_perm = bdrv_mirror_top_child_perm, .bdrv_refresh_limits = bdrv_mirror_top_refresh_limits, + + .is_filter = true, }; static BlockJob *mirror_start_job( From patchwork Fri Aug 9 16:13:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087015 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 389501399 for ; Fri, 9 Aug 2019 16:15:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 26A2E1FF28 for ; Fri, 9 Aug 2019 16:15:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1B2A2201B0; Fri, 9 Aug 2019 16:15:05 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id BCB0720223 for ; Fri, 9 Aug 2019 16:15:04 +0000 (UTC) Received: from localhost ([::1]:60790 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Xk-0002Lo-4H for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:15:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56677) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7X3-0000JY-1e for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7X0-0003s7-Pe for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:20 -0400 Received: from mx1.redhat.com ([209.132.183.28]:60956) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Wx-0003pS-P2; Fri, 09 Aug 2019 12:14:15 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1971C307D921; Fri, 9 Aug 2019 16:14:14 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id AB1FC608C2; Fri, 9 Aug 2019 16:14:13 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:27 +0200 Message-Id: <20190809161407.11920-3-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Fri, 09 Aug 2019 16:14:14 +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 v6 02/42] copy-on-read: Support compressed writes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/copy-on-read.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/block/copy-on-read.c b/block/copy-on-read.c index 6631f30205..16bdf630b6 100644 --- a/block/copy-on-read.c +++ b/block/copy-on-read.c @@ -113,6 +113,16 @@ static int coroutine_fn cor_co_pdiscard(BlockDriverState *bs, } +static int coroutine_fn cor_co_pwritev_compressed(BlockDriverState *bs, + uint64_t offset, + uint64_t bytes, + QEMUIOVector *qiov) +{ + return bdrv_co_pwritev(bs->file, offset, bytes, qiov, + BDRV_REQ_WRITE_COMPRESSED); +} + + static void cor_eject(BlockDriverState *bs, bool eject_flag) { bdrv_eject(bs->file->bs, eject_flag); @@ -145,6 +155,7 @@ static BlockDriver bdrv_copy_on_read = { .bdrv_co_pwritev = cor_co_pwritev, .bdrv_co_pwrite_zeroes = cor_co_pwrite_zeroes, .bdrv_co_pdiscard = cor_co_pdiscard, + .bdrv_co_pwritev_compressed = cor_co_pwritev_compressed, .bdrv_eject = cor_eject, .bdrv_lock_medium = cor_lock_medium, From patchwork Fri Aug 9 16:13:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087111 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 9B47B6C5 for ; Fri, 9 Aug 2019 16:16:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8850A201CB for ; Fri, 9 Aug 2019 16:16:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7BCBF20223; Fri, 9 Aug 2019 16:16:26 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2EC03201F3 for ; Fri, 9 Aug 2019 16:16:26 +0000 (UTC) Received: from localhost ([::1]:60834 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Z3-00066g-CV for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:16:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56718) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7X5-0000NU-KT for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7X4-0003v8-JN for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:23 -0400 Received: from mx1.redhat.com ([209.132.183.28]:60200) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Wz-0003qr-Jo; Fri, 09 Aug 2019 12:14:17 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 57CC65CC; Fri, 9 Aug 2019 16:14:16 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E69755D9C3; Fri, 9 Aug 2019 16:14:15 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:28 +0200 Message-Id: <20190809161407.11920-4-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 09 Aug 2019 16:14:16 +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 v6 03/42] throttle: Support compressed writes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/throttle.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/block/throttle.c b/block/throttle.c index 0349f42257..958a2bcfa6 100644 --- a/block/throttle.c +++ b/block/throttle.c @@ -153,6 +153,15 @@ static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs, return bdrv_co_pdiscard(bs->file, offset, bytes); } +static int coroutine_fn throttle_co_pwritev_compressed(BlockDriverState *bs, + uint64_t offset, + uint64_t bytes, + QEMUIOVector *qiov) +{ + return throttle_co_pwritev(bs, offset, bytes, qiov, + BDRV_REQ_WRITE_COMPRESSED); +} + static int throttle_co_flush(BlockDriverState *bs) { return bdrv_co_flush(bs->file->bs); @@ -251,6 +260,7 @@ static BlockDriver bdrv_throttle = { .bdrv_co_pwrite_zeroes = throttle_co_pwrite_zeroes, .bdrv_co_pdiscard = throttle_co_pdiscard, + .bdrv_co_pwritev_compressed = throttle_co_pwritev_compressed, .bdrv_recurse_is_first_non_filter = throttle_recurse_is_first_non_filter, From patchwork Fri Aug 9 16:13:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087135 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 A5FEB13AC for ; Fri, 9 Aug 2019 16:17:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 941DF20223 for ; Fri, 9 Aug 2019 16:17:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8853C2023F; Fri, 9 Aug 2019 16:17:59 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id F277A201F3 for ; Fri, 9 Aug 2019 16:17:58 +0000 (UTC) Received: from localhost ([::1]:60860 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7aY-0001Dm-93 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:17:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56789) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7X9-0000ZD-5L for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7X7-0003xv-Mz for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:32792) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7X3-0003sN-1C; Fri, 09 Aug 2019 12:14:22 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C0007307D989; Fri, 9 Aug 2019 16:14:18 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2C418600CD; Fri, 9 Aug 2019 16:14:17 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:29 +0200 Message-Id: <20190809161407.11920-5-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Fri, 09 Aug 2019 16:14:18 +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 v6 04/42] block: Add child access functions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP There are BDS children that the general block layer code can access, namely bs->file and bs->backing. Since the introduction of filters and external data files, their meaning is not quite clear. bs->backing can be a COW source, or it can be an R/W-filtered child; bs->file can be an R/W-filtered child, it can be data and metadata storage, or it can be just metadata storage. This overloading really is not helpful. This patch adds function that retrieve the correct child for each exact purpose. Later patches in this series will make use of them. Doing so will allow us to handle filter nodes and external data files in a meaningful way. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- include/block/block_int.h | 57 ++++++++++++++++++++-- block.c | 99 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 3 deletions(-) diff --git a/include/block/block_int.h b/include/block/block_int.h index 60d9261f8e..6c60abc4c3 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -90,9 +90,11 @@ struct BlockDriver { int instance_size; /* set to true if the BlockDriver is a block filter. Block filters pass - * certain callbacks that refer to data (see block.c) to their bs->file if - * the driver doesn't implement them. Drivers that do not wish to forward - * must implement them and return -ENOTSUP. + * certain callbacks that refer to data (see block.c) to their bs->file + * or bs->backing (whichever one exists) if the driver doesn't implement + * them. Drivers that do not wish to forward must implement them and return + * -ENOTSUP. + * Note that filters are not allowed to modify data. */ bool is_filter; /* for snapshots block filter like Quorum can implement the @@ -562,6 +564,13 @@ struct BlockDriver { * If this pointer is NULL, the array is considered empty. * "filename" and "driver" are always considered strong. */ const char *const *strong_runtime_opts; + + /** + * Return the data storage child, if there is exactly one. If + * this function is not implemented, the block layer will assume + * bs->file to be this child. + */ + BdrvChild *(*bdrv_storage_child)(BlockDriverState *bs); }; typedef struct BlockLimits { @@ -1276,4 +1285,46 @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, uint64_t src_offset, int refresh_total_sectors(BlockDriverState *bs, int64_t hint); +BdrvChild *bdrv_filtered_cow_child(BlockDriverState *bs); +BdrvChild *bdrv_filtered_rw_child(BlockDriverState *bs); +BdrvChild *bdrv_filtered_child(BlockDriverState *bs); +BdrvChild *bdrv_metadata_child(BlockDriverState *bs); +BdrvChild *bdrv_storage_child(BlockDriverState *bs); +BdrvChild *bdrv_primary_child(BlockDriverState *bs); + +static inline BlockDriverState *child_bs(BdrvChild *child) +{ + return child ? child->bs : NULL; +} + +static inline BlockDriverState *bdrv_filtered_cow_bs(BlockDriverState *bs) +{ + return child_bs(bdrv_filtered_cow_child(bs)); +} + +static inline BlockDriverState *bdrv_filtered_rw_bs(BlockDriverState *bs) +{ + return child_bs(bdrv_filtered_rw_child(bs)); +} + +static inline BlockDriverState *bdrv_filtered_bs(BlockDriverState *bs) +{ + return child_bs(bdrv_filtered_child(bs)); +} + +static inline BlockDriverState *bdrv_metadata_bs(BlockDriverState *bs) +{ + return child_bs(bdrv_metadata_child(bs)); +} + +static inline BlockDriverState *bdrv_storage_bs(BlockDriverState *bs) +{ + return child_bs(bdrv_storage_child(bs)); +} + +static inline BlockDriverState *bdrv_primary_bs(BlockDriverState *bs) +{ + return child_bs(bdrv_primary_child(bs)); +} + #endif /* BLOCK_INT_H */ diff --git a/block.c b/block.c index aae3417dd5..f6c5f8c3eb 100644 --- a/block.c +++ b/block.c @@ -6556,3 +6556,102 @@ bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name, return drv->bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp); } + +/* + * Return the child that @bs acts as an overlay for, and from which data may be + * copied in COW or COR operations. Usually this is the backing file. + */ +BdrvChild *bdrv_filtered_cow_child(BlockDriverState *bs) +{ + if (!bs || !bs->drv) { + return NULL; + } + + if (bs->drv->is_filter) { + return NULL; + } + + return bs->backing; +} + +/* + * If @bs acts as a pass-through filter for one of its children, + * return that child. "Pass-through" means that write operations to + * @bs are forwarded to that child instead of triggering COW. + */ +BdrvChild *bdrv_filtered_rw_child(BlockDriverState *bs) +{ + if (!bs || !bs->drv) { + return NULL; + } + + if (!bs->drv->is_filter) { + return NULL; + } + + /* Only one of @backing or @file may be used */ + assert(!(bs->backing && bs->file)); + + return bs->backing ?: bs->file; +} + +/* + * Return any filtered child, independently of how it reacts to write + * accesses and whether data is copied onto this BDS through COR. + */ +BdrvChild *bdrv_filtered_child(BlockDriverState *bs) +{ + BdrvChild *cow_child = bdrv_filtered_cow_child(bs); + BdrvChild *rw_child = bdrv_filtered_rw_child(bs); + + /* There can only be one filtered child at a time */ + assert(!(cow_child && rw_child)); + + return cow_child ?: rw_child; +} + +/* + * Return the child that stores the metadata for this node. + */ +BdrvChild *bdrv_metadata_child(BlockDriverState *bs) +{ + if (!bs || !bs->drv) { + return NULL; + } + + /* Filters do not have metadata */ + if (bs->drv->is_filter) { + return NULL; + } + + return bs->file; +} + +/* + * Return the child that stores the data that is allocated on this + * node. This may or may not include metadata. + */ +BdrvChild *bdrv_storage_child(BlockDriverState *bs) +{ + if (!bs || !bs->drv) { + return NULL; + } + + if (bs->drv->bdrv_storage_child) { + return bs->drv->bdrv_storage_child(bs); + } + + return bdrv_filtered_rw_child(bs) ?: bs->file; +} + +/* + * Return the primary child of this node: For filters, that is the + * filtered child. For other nodes, that is usually the child storing + * metadata. + * (A generally more helpful description is that this is (usually) the + * child that has the same filename as @bs.) + */ +BdrvChild *bdrv_primary_child(BlockDriverState *bs) +{ + return bdrv_filtered_rw_child(bs) ?: bs->file; +} From patchwork Fri Aug 9 16:13:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087129 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 350BE6C5 for ; Fri, 9 Aug 2019 16:16:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 23D382022B for ; Fri, 9 Aug 2019 16:16:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 186D71FFE4; Fri, 9 Aug 2019 16:16:40 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B0C961FF87 for ; Fri, 9 Aug 2019 16:16:39 +0000 (UTC) Received: from localhost ([::1]:60836 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7ZH-0006rb-26 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:16:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56774) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7X8-0000Xs-Ha for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7X7-0003xi-Eu for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58156) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7X4-0003tH-HV; Fri, 09 Aug 2019 12:14:23 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0B0B18E90E; Fri, 9 Aug 2019 16:14:21 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9BD7919C70; Fri, 9 Aug 2019 16:14:20 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:30 +0200 Message-Id: <20190809161407.11920-6-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Fri, 09 Aug 2019 16:14:21 +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 v6 05/42] block: Add chain helper functions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add some helper functions for skipping filters in a chain of block nodes. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- include/block/block_int.h | 3 +++ block.c | 55 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/include/block/block_int.h b/include/block/block_int.h index 6c60abc4c3..5bec3361fd 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -1291,6 +1291,9 @@ BdrvChild *bdrv_filtered_child(BlockDriverState *bs); BdrvChild *bdrv_metadata_child(BlockDriverState *bs); BdrvChild *bdrv_storage_child(BlockDriverState *bs); BdrvChild *bdrv_primary_child(BlockDriverState *bs); +BlockDriverState *bdrv_skip_implicit_filters(BlockDriverState *bs); +BlockDriverState *bdrv_skip_rw_filters(BlockDriverState *bs); +BlockDriverState *bdrv_backing_chain_next(BlockDriverState *bs); static inline BlockDriverState *child_bs(BdrvChild *child) { diff --git a/block.c b/block.c index f6c5f8c3eb..bfa5e27850 100644 --- a/block.c +++ b/block.c @@ -6655,3 +6655,58 @@ BdrvChild *bdrv_primary_child(BlockDriverState *bs) { return bdrv_filtered_rw_child(bs) ?: bs->file; } + +static BlockDriverState *bdrv_skip_filters(BlockDriverState *bs, + bool stop_on_explicit_filter) +{ + BdrvChild *filtered; + + if (!bs) { + return NULL; + } + + while (!(stop_on_explicit_filter && !bs->implicit)) { + filtered = bdrv_filtered_rw_child(bs); + if (!filtered) { + break; + } + bs = filtered->bs; + } + /* + * Note that this treats nodes with bs->drv == NULL as not being + * R/W filters (bs->drv == NULL should be replaced by something + * else anyway). + * The advantage of this behavior is that this function will thus + * always return a non-NULL value (given a non-NULL @bs). + */ + + return bs; +} + +/* + * Return the first BDS that has not been added implicitly or that + * does not have an RW-filtered child down the chain starting from @bs + * (including @bs itself). + */ +BlockDriverState *bdrv_skip_implicit_filters(BlockDriverState *bs) +{ + return bdrv_skip_filters(bs, true); +} + +/* + * Return the first BDS that does not have an RW-filtered child down + * the chain starting from @bs (including @bs itself). + */ +BlockDriverState *bdrv_skip_rw_filters(BlockDriverState *bs) +{ + return bdrv_skip_filters(bs, false); +} + +/* + * For a backing chain, return the first non-filter backing image of + * the first non-filter image. + */ +BlockDriverState *bdrv_backing_chain_next(BlockDriverState *bs) +{ + return bdrv_skip_rw_filters(bdrv_filtered_cow_bs(bdrv_skip_rw_filters(bs))); +} From patchwork Fri Aug 9 16:13:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087033 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 3292B6C5 for ; Fri, 9 Aug 2019 16:15:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 217061FF87 for ; Fri, 9 Aug 2019 16:15:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1599A20223; Fri, 9 Aug 2019 16:15:13 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A10251FF28 for ; Fri, 9 Aug 2019 16:15:12 +0000 (UTC) Received: from localhost ([::1]:60796 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Xr-0002n4-NU for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:15:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56788) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7X9-0000ZB-4z for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7X8-0003yC-6k for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58392) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7X5-0003vu-VK; Fri, 09 Aug 2019 12:14:24 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4C4A43078A2E; Fri, 9 Aug 2019 16:14:23 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D99B25D9C3; Fri, 9 Aug 2019 16:14:22 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:31 +0200 Message-Id: <20190809161407.11920-7-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Fri, 09 Aug 2019 16:14:23 +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 v6 06/42] qcow2: Implement .bdrv_storage_child() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- block/qcow2.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/block/qcow2.c b/block/qcow2.c index 039bdc2f7e..f8570d6210 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -5086,6 +5086,13 @@ void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset, s->signaled_corruption = true; } +static BdrvChild *qcow2_storage_child(BlockDriverState *bs) +{ + BDRVQcow2State *s = bs->opaque; + + return s->data_file; +} + static QemuOptsList qcow2_create_opts = { .name = "qcow2-create-opts", .head = QTAILQ_HEAD_INITIALIZER(qcow2_create_opts.head), @@ -5232,6 +5239,8 @@ BlockDriver bdrv_qcow2 = { .bdrv_reopen_bitmaps_rw = qcow2_reopen_bitmaps_rw, .bdrv_can_store_new_dirty_bitmap = qcow2_can_store_new_dirty_bitmap, .bdrv_remove_persistent_dirty_bitmap = qcow2_remove_persistent_dirty_bitmap, + + .bdrv_storage_child = qcow2_storage_child, }; static void bdrv_qcow2_init(void) From patchwork Fri Aug 9 16:13:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087137 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 6E27213AC for ; Fri, 9 Aug 2019 16:18:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5C0BD20072 for ; Fri, 9 Aug 2019 16:18:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 502A62023F; Fri, 9 Aug 2019 16:18:26 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D1D1620072 for ; Fri, 9 Aug 2019 16:18:25 +0000 (UTC) Received: from localhost ([::1]:60862 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7az-0001vt-77 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:18:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56819) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7XB-0000e9-D3 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7XA-0003zR-CS for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:29 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53644) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7X8-0003xz-7o; Fri, 09 Aug 2019 12:14:26 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 87E2C30FB8F1; Fri, 9 Aug 2019 16:14:25 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2563A10013A1; Fri, 9 Aug 2019 16:14:24 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:32 +0200 Message-Id: <20190809161407.11920-8-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Fri, 09 Aug 2019 16:14:25 +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 v6 07/42] block: *filtered_cow_child() for *has_zero_init() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP bdrv_has_zero_init() and the related bdrv_unallocated_blocks_are_zero() should use bdrv_filtered_cow_child() if they want to check whether the given BDS has a COW backing file. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index bfa5e27850..486c75d847 100644 --- a/block.c +++ b/block.c @@ -5063,7 +5063,7 @@ int bdrv_has_zero_init(BlockDriverState *bs) /* If BS is a copy on write image, it is initialized to the contents of the base image, which may not be zeroes. */ - if (bs->backing) { + if (bdrv_filtered_cow_child(bs)) { return 0; } if (bs->drv->bdrv_has_zero_init) { @@ -5081,7 +5081,7 @@ bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs) { BlockDriverInfo bdi; - if (bs->backing) { + if (bdrv_filtered_cow_child(bs)) { return false; } From patchwork Fri Aug 9 16:13:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087141 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 3F3F213AC for ; Fri, 9 Aug 2019 16:19:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2D3261FF28 for ; Fri, 9 Aug 2019 16:19:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2181B20072; Fri, 9 Aug 2019 16:19:51 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C13101FF28 for ; Fri, 9 Aug 2019 16:19:50 +0000 (UTC) Received: from localhost ([::1]:60890 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7cM-0004k3-3W for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:19:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56839) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7XE-0000jQ-C9 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7XD-00040T-Bg for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:32 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36366) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7XA-0003zJ-Io; Fri, 09 Aug 2019 12:14:28 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C84B060AD4; Fri, 9 Aug 2019 16:14:27 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 644C55C578; Fri, 9 Aug 2019 16:14:27 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:33 +0200 Message-Id: <20190809161407.11920-9-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 09 Aug 2019 16:14:27 +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 v6 08/42] block: bdrv_set_backing_hd() is about bs->backing X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP bdrv_set_backing_hd() is a function that explicitly cares about the bs->backing child. Highlight that in its description and use child_bs(bs->backing) instead of backing_bs(bs) to make it more obvious. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index 486c75d847..adf82efb0e 100644 --- a/block.c +++ b/block.c @@ -2539,7 +2539,7 @@ static bool bdrv_inherits_from_recursive(BlockDriverState *child, } /* - * Sets the backing file link of a BDS. A new reference is created; callers + * Sets the bs->backing link of a BDS. A new reference is created; callers * which don't need their own reference any more must call bdrv_unref(). */ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, @@ -2548,7 +2548,7 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, bool update_inherits_from = bdrv_chain_contains(bs, backing_hd) && bdrv_inherits_from_recursive(backing_hd, bs); - if (bdrv_is_backing_chain_frozen(bs, backing_bs(bs), errp)) { + if (bdrv_is_backing_chain_frozen(bs, child_bs(bs->backing), errp)) { return; } From patchwork Fri Aug 9 16:13:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087205 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 4103713AC for ; Fri, 9 Aug 2019 16:21:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2D7F92012F for ; Fri, 9 Aug 2019 16:21:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 217F9201BC; Fri, 9 Aug 2019 16:21:14 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4765F2015F for ; Fri, 9 Aug 2019 16:21:13 +0000 (UTC) Received: from localhost ([::1]:60926 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7dg-0008MC-59 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:21:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56939) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7XK-0000yF-Pr for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7XI-00042w-Qx for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:38 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36382) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7XD-00040A-77; Fri, 09 Aug 2019 12:14:31 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3FB9A20ABB; Fri, 9 Aug 2019 16:14:30 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9E9045D9C3; Fri, 9 Aug 2019 16:14:29 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:34 +0200 Message-Id: <20190809161407.11920-10-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 09 Aug 2019 16:14:30 +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 v6 09/42] block: Include filters when freezing backing chain X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP In order to make filters work in backing chains, the associated functions must be able to deal with them and freeze all filter links, be they COW or R/W filter links. In the process, rename these functions to reflect that they now act on generalized chains of filter nodes instead of backing chains alone. While at it, add some comments that note which functions require their caller to ensure that a given child link is not frozen, and how the callers do so. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/block.h | 10 +++--- block.c | 81 +++++++++++++++++++++++++------------------ block/commit.c | 8 ++--- block/mirror.c | 4 +-- block/stream.c | 8 ++--- 5 files changed, 62 insertions(+), 49 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index 50a07c1c33..f6f09b95cd 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -364,11 +364,11 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base, BlockDriverState *bdrv_find_overlay(BlockDriverState *active, BlockDriverState *bs); BlockDriverState *bdrv_find_base(BlockDriverState *bs); -bool bdrv_is_backing_chain_frozen(BlockDriverState *bs, BlockDriverState *base, - Error **errp); -int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base, - Error **errp); -void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState *base); +bool bdrv_is_chain_frozen(BlockDriverState *bs, BlockDriverState *base, + Error **errp); +int bdrv_freeze_chain(BlockDriverState *bs, BlockDriverState *base, + Error **errp); +void bdrv_unfreeze_chain(BlockDriverState *bs, BlockDriverState *base); typedef struct BdrvCheckResult { diff --git a/block.c b/block.c index adf82efb0e..650c00d182 100644 --- a/block.c +++ b/block.c @@ -2303,12 +2303,15 @@ static void bdrv_replace_child_noperm(BdrvChild *child, * If @new_bs is not NULL, bdrv_check_perm() must be called beforehand, as this * function uses bdrv_set_perm() to update the permissions according to the new * reference that @new_bs gets. + * + * Callers must ensure that child->frozen is false. */ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs) { BlockDriverState *old_bs = child->bs; uint64_t perm, shared_perm; + /* Asserts that child->frozen == false */ bdrv_replace_child_noperm(child, new_bs); /* @@ -2468,6 +2471,7 @@ static void bdrv_detach_child(BdrvChild *child) g_free(child); } +/* Callers must ensure that child->frozen is false. */ void bdrv_root_unref_child(BdrvChild *child) { BlockDriverState *child_bs; @@ -2477,10 +2481,6 @@ void bdrv_root_unref_child(BdrvChild *child) bdrv_unref(child_bs); } -/** - * Clear all inherits_from pointers from children and grandchildren of - * @root that point to @root, where necessary. - */ static void bdrv_unset_inherits_from(BlockDriverState *root, BdrvChild *child) { BdrvChild *c; @@ -2505,6 +2505,7 @@ static void bdrv_unset_inherits_from(BlockDriverState *root, BdrvChild *child) } } +/* Callers must ensure that child->frozen is false. */ void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child) { if (child == NULL) { @@ -2548,7 +2549,7 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, bool update_inherits_from = bdrv_chain_contains(bs, backing_hd) && bdrv_inherits_from_recursive(backing_hd, bs); - if (bdrv_is_backing_chain_frozen(bs, child_bs(bs->backing), errp)) { + if (bdrv_is_chain_frozen(bs, child_bs(bs->backing), errp)) { return; } @@ -2557,6 +2558,7 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, } if (bs->backing) { + /* Cannot be frozen, we checked that above */ bdrv_unref_child(bs, bs->backing); } @@ -3674,8 +3676,7 @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state, return -EPERM; } /* Check if the backing link that we want to replace is frozen */ - if (bdrv_is_backing_chain_frozen(overlay_bs, backing_bs(overlay_bs), - errp)) { + if (bdrv_is_chain_frozen(overlay_bs, backing_bs(overlay_bs), errp)) { return -EPERM; } reopen_state->replace_backing_bs = true; @@ -4029,6 +4030,7 @@ static void bdrv_close(BlockDriverState *bs) if (bs->drv) { if (bs->drv->bdrv_close) { + /* Must unfreeze all children, so bdrv_unref_child() works */ bs->drv->bdrv_close(bs); } bs->drv = NULL; @@ -4398,20 +4400,22 @@ BlockDriverState *bdrv_find_base(BlockDriverState *bs) } /* - * Return true if at least one of the backing links between @bs and - * @base is frozen. @errp is set if that's the case. + * Return true if at least one of the (COW and R/W) filter links + * between @bs and @base is frozen. @errp is set if that's the case. * @base must be reachable from @bs, or NULL. */ -bool bdrv_is_backing_chain_frozen(BlockDriverState *bs, BlockDriverState *base, - Error **errp) +bool bdrv_is_chain_frozen(BlockDriverState *bs, BlockDriverState *base, + Error **errp) { BlockDriverState *i; + BdrvChild *child; + + for (i = bs; i != base; i = child_bs(child)) { + child = bdrv_filtered_child(i); - for (i = bs; i != base; i = backing_bs(i)) { - if (i->backing && i->backing->frozen) { + if (child && child->frozen) { error_setg(errp, "Cannot change '%s' link from '%s' to '%s'", - i->backing->name, i->node_name, - backing_bs(i)->node_name); + child->name, i->node_name, child->bs->node_name); return true; } } @@ -4420,32 +4424,35 @@ bool bdrv_is_backing_chain_frozen(BlockDriverState *bs, BlockDriverState *base, } /* - * Freeze all backing links between @bs and @base. + * Freeze all (COW and R/W) filter links between @bs and @base. * If any of the links is already frozen the operation is aborted and * none of the links are modified. * @base must be reachable from @bs, or NULL. * Returns 0 on success. On failure returns < 0 and sets @errp. */ -int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base, - Error **errp) +int bdrv_freeze_chain(BlockDriverState *bs, BlockDriverState *base, + Error **errp) { BlockDriverState *i; + BdrvChild *child; - if (bdrv_is_backing_chain_frozen(bs, base, errp)) { + if (bdrv_is_chain_frozen(bs, base, errp)) { return -EPERM; } - for (i = bs; i != base; i = backing_bs(i)) { - if (i->backing && backing_bs(i)->never_freeze) { + for (i = bs; i != base; i = child_bs(child)) { + child = bdrv_filtered_child(i); + if (child && child->bs->never_freeze) { error_setg(errp, "Cannot freeze '%s' link to '%s'", - i->backing->name, backing_bs(i)->node_name); + child->name, child->bs->node_name); return -EPERM; } } - for (i = bs; i != base; i = backing_bs(i)) { - if (i->backing) { - i->backing->frozen = true; + for (i = bs; i != base; i = child_bs(child)) { + child = bdrv_filtered_child(i); + if (child) { + child->frozen = true; } } @@ -4453,18 +4460,21 @@ int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base, } /* - * Unfreeze all backing links between @bs and @base. The caller must - * ensure that all links are frozen before using this function. + * Unfreeze all (COW and R/W) filter links between @bs and @base. The + * caller must ensure that all links are frozen before using this + * function. * @base must be reachable from @bs, or NULL. */ -void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState *base) +void bdrv_unfreeze_chain(BlockDriverState *bs, BlockDriverState *base) { BlockDriverState *i; + BdrvChild *child; - for (i = bs; i != base; i = backing_bs(i)) { - if (i->backing) { - assert(i->backing->frozen); - i->backing->frozen = false; + for (i = bs; i != base; i = child_bs(child)) { + child = bdrv_filtered_child(i); + if (child) { + assert(child->frozen); + child->frozen = false; } } } @@ -4567,8 +4577,11 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base, } } - /* Do the actual switch in the in-memory graph. - * Completes bdrv_check_update_perm() transaction internally. */ + /* + * Do the actual switch in the in-memory graph. + * Completes bdrv_check_update_perm() transaction internally. + * c->frozen is false, we have checked that above. + */ bdrv_ref(base); bdrv_replace_child(c, base); bdrv_unref(top); diff --git a/block/commit.c b/block/commit.c index 19915603ae..5a7672c7c7 100644 --- a/block/commit.c +++ b/block/commit.c @@ -68,7 +68,7 @@ static int commit_prepare(Job *job) { CommitBlockJob *s = container_of(job, CommitBlockJob, common.job); - bdrv_unfreeze_backing_chain(s->commit_top_bs, s->base_bs); + bdrv_unfreeze_chain(s->commit_top_bs, s->base_bs); s->chain_frozen = false; /* Remove base node parent that still uses BLK_PERM_WRITE/RESIZE before @@ -88,7 +88,7 @@ static void commit_abort(Job *job) BlockDriverState *top_bs = blk_bs(s->top); if (s->chain_frozen) { - bdrv_unfreeze_backing_chain(s->commit_top_bs, s->base_bs); + bdrv_unfreeze_chain(s->commit_top_bs, s->base_bs); } /* Make sure commit_top_bs and top stay around until bdrv_replace_node() */ @@ -331,7 +331,7 @@ void commit_start(const char *job_id, BlockDriverState *bs, } } - if (bdrv_freeze_backing_chain(commit_top_bs, base, errp) < 0) { + if (bdrv_freeze_chain(commit_top_bs, base, errp) < 0) { goto fail; } s->chain_frozen = true; @@ -372,7 +372,7 @@ void commit_start(const char *job_id, BlockDriverState *bs, fail: if (s->chain_frozen) { - bdrv_unfreeze_backing_chain(commit_top_bs, base); + bdrv_unfreeze_chain(commit_top_bs, base); } if (s->base) { blk_unref(s->base); diff --git a/block/mirror.c b/block/mirror.c index a8f2d7a305..54bafdf176 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -633,7 +633,7 @@ static int mirror_exit_common(Job *job) s->prepared = true; if (bdrv_chain_contains(src, target_bs)) { - bdrv_unfreeze_backing_chain(mirror_top_bs, target_bs); + bdrv_unfreeze_chain(mirror_top_bs, target_bs); } bdrv_release_dirty_bitmap(src, s->dirty_bitmap); @@ -1707,7 +1707,7 @@ static BlockJob *mirror_start_job( } } - if (bdrv_freeze_backing_chain(mirror_top_bs, target, errp) < 0) { + if (bdrv_freeze_chain(mirror_top_bs, target, errp) < 0) { goto fail; } } diff --git a/block/stream.c b/block/stream.c index 6ac1e7bec4..4c8b89884a 100644 --- a/block/stream.c +++ b/block/stream.c @@ -54,7 +54,7 @@ static void stream_abort(Job *job) if (s->chain_frozen) { BlockJob *bjob = &s->common; - bdrv_unfreeze_backing_chain(blk_bs(bjob->blk), s->bottom); + bdrv_unfreeze_chain(blk_bs(bjob->blk), s->bottom); } } @@ -67,7 +67,7 @@ static int stream_prepare(Job *job) Error *local_err = NULL; int ret = 0; - bdrv_unfreeze_backing_chain(bs, s->bottom); + bdrv_unfreeze_chain(bs, s->bottom); s->chain_frozen = false; if (bs->backing) { @@ -233,7 +233,7 @@ void stream_start(const char *job_id, BlockDriverState *bs, int basic_flags = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED; BlockDriverState *bottom = bdrv_find_overlay(bs, base); - if (bdrv_freeze_backing_chain(bs, bottom, errp) < 0) { + if (bdrv_freeze_chain(bs, bottom, errp) < 0) { return; } @@ -284,5 +284,5 @@ fail: if (bs_read_only) { bdrv_reopen_set_read_only(bs, true, NULL); } - bdrv_unfreeze_backing_chain(bs, bottom); + bdrv_unfreeze_chain(bs, bottom); } From patchwork Fri Aug 9 16:13:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087171 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 1220E14D5 for ; Fri, 9 Aug 2019 16:20:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F41861FF87 for ; Fri, 9 Aug 2019 16:20:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E7DB92015F; Fri, 9 Aug 2019 16:20:29 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 893AC1FF87 for ; Fri, 9 Aug 2019 16:20:19 +0000 (UTC) Received: from localhost ([::1]:60894 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7cc-0005Vl-Pz for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:20:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56910) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7XK-0000ug-1T for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7XI-00042q-Qc for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53412) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7XF-000410-5q; Fri, 09 Aug 2019 12:14:33 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 808283082B1F; Fri, 9 Aug 2019 16:14:32 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 19784600CC; Fri, 9 Aug 2019 16:14:31 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:35 +0200 Message-Id: <20190809161407.11920-11-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Fri, 09 Aug 2019 16:14:32 +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 v6 10/42] block: Drop bdrv_is_encrypted() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP The original purpose of bdrv_is_encrypted() was to inquire whether a BDS can be used without the user entering a password or not. It has not been used for that purpose for quite some time. Actually, it is not even fit for that purpose, because to answer that question, it would have recursively query all of the given node's children. So now we have to decide in which direction we want to fix bdrv_is_encrypted(): Recursively query all children, or drop it and just use bs->encrypted to get the current node's status? Nowadays, its only purpose is to report through bdrv_query_image_info() whether the given image is encrypted or not. For this purpose, it is probably more interesting to see whether a given node itself is encrypted or not (otherwise, a management application cannot discern for certain which nodes are really encrypted and which just have encrypted children). Suggested-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/block.h | 1 - block.c | 8 -------- block/qapi.c | 2 +- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index f6f09b95cd..9cfe77abaf 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -487,7 +487,6 @@ BlockDriverState *bdrv_next(BdrvNextIterator *it); void bdrv_next_cleanup(BdrvNextIterator *it); BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs); -bool bdrv_is_encrypted(BlockDriverState *bs); void bdrv_iterate_format(void (*it)(void *opaque, const char *name), void *opaque, bool read_only); const char *bdrv_get_node_name(const BlockDriverState *bs); diff --git a/block.c b/block.c index 650c00d182..415c555bf5 100644 --- a/block.c +++ b/block.c @@ -4696,14 +4696,6 @@ bool bdrv_is_sg(BlockDriverState *bs) return bs->sg; } -bool bdrv_is_encrypted(BlockDriverState *bs) -{ - if (bs->backing && bs->backing->bs->encrypted) { - return true; - } - return bs->encrypted; -} - const char *bdrv_get_format_name(BlockDriverState *bs) { return bs->drv ? bs->drv->format_name : NULL; diff --git a/block/qapi.c b/block/qapi.c index 15f1030264..9a185cba48 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -281,7 +281,7 @@ void bdrv_query_image_info(BlockDriverState *bs, info->virtual_size = size; info->actual_size = bdrv_get_allocated_file_size(bs); info->has_actual_size = info->actual_size >= 0; - if (bdrv_is_encrypted(bs)) { + if (bs->encrypted) { info->encrypted = true; info->has_encrypted = true; } From patchwork Fri Aug 9 16:13:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087213 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 83D3E14D5 for ; Fri, 9 Aug 2019 16:22:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 717E32012F for ; Fri, 9 Aug 2019 16:22:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 65AF6201BD; Fri, 9 Aug 2019 16:22:30 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id F2DD1201A4 for ; Fri, 9 Aug 2019 16:22:29 +0000 (UTC) Received: from localhost ([::1]:60956 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7ev-0003MH-Bc for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:22:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56991) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7XM-00013h-Cd for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7XL-00046J-7p for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:40 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52036) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7XI-000424-J7; Fri, 09 Aug 2019 12:14:36 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C190059451; Fri, 9 Aug 2019 16:14:34 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5B3C95C8BA; Fri, 9 Aug 2019 16:14:34 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:36 +0200 Message-Id: <20190809161407.11920-12-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 09 Aug 2019 16:14:34 +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 v6 11/42] block: Add bdrv_supports_compressed_writes() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Filters cannot compress data themselves but they have to implement .bdrv_co_pwritev_compressed() still (or they cannot forward compressed writes). Therefore, checking whether bs->drv->bdrv_co_pwritev_compressed is non-NULL is not sufficient to know whether the node can actually handle compressed writes. This function looks down the filter chain to see whether there is a non-filter that can actually convert the compressed writes into compressed data (and thus normal writes). Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/block.h | 1 + block.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/include/block/block.h b/include/block/block.h index 9cfe77abaf..6ba853fb90 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -487,6 +487,7 @@ BlockDriverState *bdrv_next(BdrvNextIterator *it); void bdrv_next_cleanup(BdrvNextIterator *it); BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs); +bool bdrv_supports_compressed_writes(BlockDriverState *bs); void bdrv_iterate_format(void (*it)(void *opaque, const char *name), void *opaque, bool read_only); const char *bdrv_get_node_name(const BlockDriverState *bs); diff --git a/block.c b/block.c index 415c555bf5..029c809a8e 100644 --- a/block.c +++ b/block.c @@ -4696,6 +4696,28 @@ bool bdrv_is_sg(BlockDriverState *bs) return bs->sg; } +/** + * Return whether the given node supports compressed writes. + */ +bool bdrv_supports_compressed_writes(BlockDriverState *bs) +{ + BlockDriverState *filtered = bdrv_filtered_rw_bs(bs); + + if (!bs->drv || !bs->drv->bdrv_co_pwritev_compressed) { + return false; + } + + if (filtered) { + /* + * Filters can only forward compressed writes, so we have to + * check the child. + */ + return bdrv_supports_compressed_writes(filtered); + } + + return true; +} + const char *bdrv_get_format_name(BlockDriverState *bs) { return bs->drv ? bs->drv->format_name : NULL; From patchwork Fri Aug 9 16:13:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087131 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 EE1C16C5 for ; Fri, 9 Aug 2019 16:16:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DA54520246 for ; Fri, 9 Aug 2019 16:16:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CE629201CB; Fri, 9 Aug 2019 16:16:47 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6B01B1FF73 for ; Fri, 9 Aug 2019 16:16:47 +0000 (UTC) Received: from localhost ([::1]:60838 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7ZO-0007J3-QT for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:16:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57023) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7XN-00018O-JS for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7XM-00047A-I5 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:41 -0400 Received: from mx1.redhat.com ([209.132.183.28]:60080) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7XJ-00043G-Lw; Fri, 09 Aug 2019 12:14:37 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0A1E630BA06F; Fri, 9 Aug 2019 16:14:37 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9A73D10013A1; Fri, 9 Aug 2019 16:14:36 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:37 +0200 Message-Id: <20190809161407.11920-13-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 09 Aug 2019 16:14:37 +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 v6 12/42] block: Use bdrv_filtered_rw* where obvious X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Places that use patterns like if (bs->drv->is_filter && bs->file) { ... something about bs->file->bs ... } should be BlockDriverState *filtered = bdrv_filtered_rw_bs(bs); if (filtered) { ... something about @filtered ... } instead. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block.c | 23 +++++++++++++++-------- block/io.c | 5 +++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/block.c b/block.c index 029c809a8e..86b84bea21 100644 --- a/block.c +++ b/block.c @@ -556,11 +556,12 @@ int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp) int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz) { BlockDriver *drv = bs->drv; + BlockDriverState *filtered = bdrv_filtered_rw_bs(bs); if (drv && drv->bdrv_probe_blocksizes) { return drv->bdrv_probe_blocksizes(bs, bsz); - } else if (drv && drv->is_filter && bs->file) { - return bdrv_probe_blocksizes(bs->file->bs, bsz); + } else if (filtered) { + return bdrv_probe_blocksizes(filtered, bsz); } return -ENOTSUP; @@ -575,11 +576,12 @@ int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz) int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo) { BlockDriver *drv = bs->drv; + BlockDriverState *filtered = bdrv_filtered_rw_bs(bs); if (drv && drv->bdrv_probe_geometry) { return drv->bdrv_probe_geometry(bs, geo); - } else if (drv && drv->is_filter && bs->file) { - return bdrv_probe_geometry(bs->file->bs, geo); + } else if (filtered) { + return bdrv_probe_geometry(filtered, geo); } return -ENOTSUP; @@ -5084,6 +5086,8 @@ int bdrv_has_zero_init_1(BlockDriverState *bs) int bdrv_has_zero_init(BlockDriverState *bs) { + BlockDriverState *filtered; + if (!bs->drv) { return 0; } @@ -5096,8 +5100,10 @@ int bdrv_has_zero_init(BlockDriverState *bs) if (bs->drv->bdrv_has_zero_init) { return bs->drv->bdrv_has_zero_init(bs); } - if (bs->file && bs->drv->is_filter) { - return bdrv_has_zero_init(bs->file->bs); + + filtered = bdrv_filtered_rw_bs(bs); + if (filtered) { + return bdrv_has_zero_init(filtered); } /* safe default */ @@ -5142,8 +5148,9 @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) return -ENOMEDIUM; } if (!drv->bdrv_get_info) { - if (bs->file && drv->is_filter) { - return bdrv_get_info(bs->file->bs, bdi); + BlockDriverState *filtered = bdrv_filtered_rw_bs(bs); + if (filtered) { + return bdrv_get_info(filtered, bdi); } return -ENOTSUP; } diff --git a/block/io.c b/block/io.c index 06305c6ea6..4d6cf4b3c2 100644 --- a/block/io.c +++ b/block/io.c @@ -3186,8 +3186,9 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, } if (!drv->bdrv_co_truncate) { - if (bs->file && drv->is_filter) { - ret = bdrv_co_truncate(bs->file, offset, prealloc, errp); + BdrvChild *filtered = bdrv_filtered_rw_child(bs); + if (filtered) { + ret = bdrv_co_truncate(filtered, offset, prealloc, errp); goto out; } error_setg(errp, "Image format driver does not support resize"); From patchwork Fri Aug 9 16:13:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087221 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 7190B13AC for ; Fri, 9 Aug 2019 16:24:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 611141FF28 for ; Fri, 9 Aug 2019 16:24:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 55CDC2015F; Fri, 9 Aug 2019 16:24:30 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 007641FF28 for ; Fri, 9 Aug 2019 16:24:29 +0000 (UTC) Received: from localhost ([::1]:60986 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7gr-0006yG-C2 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:24:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57057) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7XP-0001FH-GS for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7XO-00048L-EV for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46712) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7XM-00046b-0y; Fri, 09 Aug 2019 12:14:40 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 509DE30BB8F7; Fri, 9 Aug 2019 16:14:39 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D935D600CE; Fri, 9 Aug 2019 16:14:38 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:38 +0200 Message-Id: <20190809161407.11920-14-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Fri, 09 Aug 2019 16:14:39 +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 v6 13/42] block: Use CAFs in block status functions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Use the child access functions in the block status inquiry functions as appropriate. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/io.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/block/io.c b/block/io.c index 4d6cf4b3c2..c5a8e3e6a3 100644 --- a/block/io.c +++ b/block/io.c @@ -2180,11 +2180,12 @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs, if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) { ret |= BDRV_BLOCK_ALLOCATED; } else if (want_zero) { + BlockDriverState *cow_bs = bdrv_filtered_cow_bs(bs); + if (bdrv_unallocated_blocks_are_zero(bs)) { ret |= BDRV_BLOCK_ZERO; - } else if (bs->backing) { - BlockDriverState *bs2 = bs->backing->bs; - int64_t size2 = bdrv_getlength(bs2); + } else if (cow_bs) { + int64_t size2 = bdrv_getlength(cow_bs); if (size2 >= 0 && offset >= size2) { ret |= BDRV_BLOCK_ZERO; @@ -2250,7 +2251,7 @@ static int coroutine_fn bdrv_co_block_status_above(BlockDriverState *bs, bool first = true; assert(bs != base); - for (p = bs; p != base; p = backing_bs(p)) { + for (p = bs; p != base; p = bdrv_filtered_bs(p)) { ret = bdrv_co_block_status(p, want_zero, offset, bytes, pnum, map, file); if (ret < 0) { @@ -2336,7 +2337,7 @@ int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base, int bdrv_block_status(BlockDriverState *bs, int64_t offset, int64_t bytes, int64_t *pnum, int64_t *map, BlockDriverState **file) { - return bdrv_block_status_above(bs, backing_bs(bs), + return bdrv_block_status_above(bs, bdrv_filtered_bs(bs), offset, bytes, pnum, map, file); } @@ -2346,9 +2347,9 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int ret; int64_t dummy; - ret = bdrv_common_block_status_above(bs, backing_bs(bs), false, offset, - bytes, pnum ? pnum : &dummy, NULL, - NULL); + ret = bdrv_common_block_status_above(bs, bdrv_filtered_bs(bs), false, + offset, bytes, pnum ? pnum : &dummy, + NULL, NULL); if (ret < 0) { return ret; } @@ -2411,7 +2412,7 @@ int bdrv_is_allocated_above(BlockDriverState *top, break; } - intermediate = backing_bs(intermediate); + intermediate = bdrv_filtered_bs(intermediate); } *pnum = n; From patchwork Fri Aug 9 16:13:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087133 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 369DB6C5 for ; Fri, 9 Aug 2019 16:16:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 24D9E20223 for ; Fri, 9 Aug 2019 16:16:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 196E42022B; Fri, 9 Aug 2019 16:16:49 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A7F501FF87 for ; Fri, 9 Aug 2019 16:16:48 +0000 (UTC) Received: from localhost ([::1]:60840 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7ZQ-0007Mc-0X for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:16:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57092) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7XS-0001PC-7O for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7XR-00049i-1A for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:46 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53876) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7XO-000484-9K; Fri, 09 Aug 2019 12:14:42 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 912AE30BC9C6; Fri, 9 Aug 2019 16:14:41 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2A2DA5D6A5; Fri, 9 Aug 2019 16:14:40 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:39 +0200 Message-Id: <20190809161407.11920-15-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Fri, 09 Aug 2019 16:14:41 +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 v6 14/42] block: Use CAFs when working with backing chains X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Use child access functions when iterating through backing chains so filters do not break the chain. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/block.c b/block.c index 86b84bea21..42abbaf0ba 100644 --- a/block.c +++ b/block.c @@ -4376,7 +4376,8 @@ int bdrv_change_backing_file(BlockDriverState *bs, } /* - * Finds the image layer in the chain that has 'bs' as its backing file. + * Finds the image layer in the chain that has 'bs' (or a filter on + * top of it) as its backing file. * * active is the current topmost image. * @@ -4388,11 +4389,18 @@ int bdrv_change_backing_file(BlockDriverState *bs, BlockDriverState *bdrv_find_overlay(BlockDriverState *active, BlockDriverState *bs) { - while (active && bs != backing_bs(active)) { - active = backing_bs(active); + bs = bdrv_skip_rw_filters(bs); + active = bdrv_skip_rw_filters(active); + + while (active) { + BlockDriverState *next = bdrv_backing_chain_next(active); + if (bs == next) { + return active; + } + active = next; } - return active; + return NULL; } /* Given a BDS, searches for the base layer. */ @@ -4544,9 +4552,7 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base, * other intermediate nodes have been dropped. * If 'top' is an implicit node (e.g. "commit_top") we should skip * it because no one inherits from it. We use explicit_top for that. */ - while (explicit_top && explicit_top->implicit) { - explicit_top = backing_bs(explicit_top); - } + explicit_top = bdrv_skip_implicit_filters(explicit_top); update_inherits_from = bdrv_inherits_from_recursive(base, explicit_top); /* success - we can delete the intermediate states, and link top->base */ @@ -5014,7 +5020,7 @@ BlockDriverState *bdrv_lookup_bs(const char *device, bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base) { while (top && top != base) { - top = backing_bs(top); + top = bdrv_filtered_bs(top); } return top != NULL; @@ -5253,7 +5259,17 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, is_protocol = path_has_protocol(backing_file); - for (curr_bs = bs; curr_bs->backing; curr_bs = curr_bs->backing->bs) { + /* + * Being largely a legacy function, skip any filters here + * (because filters do not have normal filenames, so they cannot + * match anyway; and allowing json:{} filenames is a bit out of + * scope). + */ + for (curr_bs = bdrv_skip_rw_filters(bs); + bdrv_filtered_cow_child(curr_bs) != NULL; + curr_bs = bdrv_backing_chain_next(curr_bs)) + { + BlockDriverState *bs_below = bdrv_backing_chain_next(curr_bs); /* If either of the filename paths is actually a protocol, then * compare unmodified paths; otherwise make paths relative */ @@ -5261,7 +5277,7 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, char *backing_file_full_ret; if (strcmp(backing_file, curr_bs->backing_file) == 0) { - retval = curr_bs->backing->bs; + retval = bs_below; break; } /* Also check against the full backing filename for the image */ @@ -5271,7 +5287,7 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, bool equal = strcmp(backing_file, backing_file_full_ret) == 0; g_free(backing_file_full_ret); if (equal) { - retval = curr_bs->backing->bs; + retval = bs_below; break; } } @@ -5297,7 +5313,7 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, g_free(filename_tmp); if (strcmp(backing_file_full, filename_full) == 0) { - retval = curr_bs->backing->bs; + retval = bs_below; break; } } From patchwork Fri Aug 9 16:13:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087139 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 3ABCF14D5 for ; Fri, 9 Aug 2019 16:18:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 27DA11FF87 for ; Fri, 9 Aug 2019 16:18:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1C2B0201F3; Fri, 9 Aug 2019 16:18:35 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A6F211FF87 for ; Fri, 9 Aug 2019 16:18:34 +0000 (UTC) Received: from localhost ([::1]:60870 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7b7-0002Oo-V9 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:18:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57133) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7XU-0001Wn-EZ for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7XT-0004Bg-7m for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50334) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7XQ-00049E-Hj; Fri, 09 Aug 2019 12:14:44 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CF9906869A; Fri, 9 Aug 2019 16:14:43 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6948119C70; Fri, 9 Aug 2019 16:14:43 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:40 +0200 Message-Id: <20190809161407.11920-16-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Fri, 09 Aug 2019 16:14:43 +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 v6 15/42] block: Re-evaluate backing file handling in reopen X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Reopening a node's backing child needs a bit of special handling because the "backing" child has different defaults than all other children (among other things). Adding filter support here is a bit more difficult than just using the child access functions. In fact, we often have to directly use bs->backing because these functions are about the "backing" child (which may or may not be the COW backing file). Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block.c | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/block.c b/block.c index 42abbaf0ba..064cc99857 100644 --- a/block.c +++ b/block.c @@ -3660,25 +3660,56 @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state, } } + /* + * Ensure that @bs can really handle backing files, because we are + * about to give it one (or swap the existing one) + */ + if (bs->drv->is_filter) { + /* Filters always have a file or a backing child */ + if (!bs->backing) { + error_setg(errp, "'%s' is a %s filter node that does not support a " + "backing child", bs->node_name, bs->drv->format_name); + return -EINVAL; + } + } else if (!bs->drv->supports_backing) { + error_setg(errp, "Driver '%s' of node '%s' does not support backing " + "files", bs->drv->format_name, bs->node_name); + return -EINVAL; + } + /* * Find the "actual" backing file by skipping all links that point * to an implicit node, if any (e.g. a commit filter node). + * We cannot use any of the bdrv_skip_*() functions here because + * those return the first explicit node, while we are looking for + * its overlay here. */ overlay_bs = bs; - while (backing_bs(overlay_bs) && backing_bs(overlay_bs)->implicit) { - overlay_bs = backing_bs(overlay_bs); + while (bdrv_filtered_bs(overlay_bs) && + bdrv_filtered_bs(overlay_bs)->implicit) + { + overlay_bs = bdrv_filtered_bs(overlay_bs); } /* If we want to replace the backing file we need some extra checks */ - if (new_backing_bs != backing_bs(overlay_bs)) { + if (new_backing_bs != bdrv_filtered_bs(overlay_bs)) { /* Check for implicit nodes between bs and its backing file */ if (bs != overlay_bs) { error_setg(errp, "Cannot change backing link if '%s' has " "an implicit backing file", bs->node_name); return -EPERM; } - /* Check if the backing link that we want to replace is frozen */ - if (bdrv_is_chain_frozen(overlay_bs, backing_bs(overlay_bs), errp)) { + /* + * Check if the backing link that we want to replace is frozen. + * Note that + * bdrv_filtered_child(overlay_bs) == overlay_bs->backing, + * because we know that overlay_bs == bs, and that @bs + * either is an R/W filter that uses ->backing or a COW format + * with bs->drv->supports_backing == true. + */ + if (bdrv_is_chain_frozen(overlay_bs, child_bs(overlay_bs->backing), + errp)) + { return -EPERM; } reopen_state->replace_backing_bs = true; @@ -3829,7 +3860,7 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, * its metadata. Otherwise the 'backing' option can be omitted. */ if (drv->supports_backing && reopen_state->backing_missing && - (backing_bs(reopen_state->bs) || reopen_state->bs->backing_file[0])) { + (reopen_state->bs->backing || reopen_state->bs->backing_file[0])) { error_setg(errp, "backing is missing for '%s'", reopen_state->bs->node_name); ret = -EINVAL; @@ -3974,7 +4005,7 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state) * from bdrv_set_backing_hd()) has the new values. */ if (reopen_state->replace_backing_bs) { - BlockDriverState *old_backing_bs = backing_bs(bs); + BlockDriverState *old_backing_bs = child_bs(bs->backing); assert(!old_backing_bs || !old_backing_bs->implicit); /* Abort the permission update on the backing bs we're detaching */ if (old_backing_bs) { From patchwork Fri Aug 9 16:13:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087245 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 3A84214D5 for ; Fri, 9 Aug 2019 16:26:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 26CCD20499 for ; Fri, 9 Aug 2019 16:26:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1AAB820243; Fri, 9 Aug 2019 16:26:22 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B2C8B20246 for ; Fri, 9 Aug 2019 16:26:21 +0000 (UTC) Received: from localhost ([::1]:32786 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7ie-0002Tq-Vj for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:26:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57164) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7XW-0001cz-4J for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7XU-0004CZ-V1 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47086) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7XS-0004B9-P1; Fri, 09 Aug 2019 12:14:46 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1E83A30D47F6; Fri, 9 Aug 2019 16:14:46 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A7AD3600CE; Fri, 9 Aug 2019 16:14:45 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:41 +0200 Message-Id: <20190809161407.11920-17-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Fri, 09 Aug 2019 16:14:46 +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 v6 16/42] block: Flush all children in generic code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP If the driver does not support .bdrv_co_flush() so bdrv_co_flush() itself has to flush the children of the given node, it should not flush just bs->file->bs, but in fact all children. In any case, the BLKDBG_EVENT() should be emitted on the primary child, because that is where a blkdebug node would be if there is any. Suggested-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Max Reitz --- block/io.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/block/io.c b/block/io.c index c5a8e3e6a3..bcc770d336 100644 --- a/block/io.c +++ b/block/io.c @@ -2572,6 +2572,8 @@ static void coroutine_fn bdrv_flush_co_entry(void *opaque) int coroutine_fn bdrv_co_flush(BlockDriverState *bs) { + BdrvChild *primary_child = bdrv_primary_child(bs); + BdrvChild *child; int current_gen; int ret = 0; @@ -2601,7 +2603,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs) } /* Write back cached data to the OS even with cache=unsafe */ - BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_OS); + BLKDBG_EVENT(primary_child, BLKDBG_FLUSH_TO_OS); if (bs->drv->bdrv_co_flush_to_os) { ret = bs->drv->bdrv_co_flush_to_os(bs); if (ret < 0) { @@ -2611,15 +2613,15 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs) /* But don't actually force it to the disk with cache=unsafe */ if (bs->open_flags & BDRV_O_NO_FLUSH) { - goto flush_parent; + goto flush_children; } /* Check if we really need to flush anything */ if (bs->flushed_gen == current_gen) { - goto flush_parent; + goto flush_children; } - BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_DISK); + BLKDBG_EVENT(primary_child, BLKDBG_FLUSH_TO_DISK); if (!bs->drv) { /* bs->drv->bdrv_co_flush() might have ejected the BDS * (even in case of apparent success) */ @@ -2663,8 +2665,17 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs) /* Now flush the underlying protocol. It will also have BDRV_O_NO_FLUSH * in the case of cache=unsafe, so there are no useless flushes. */ -flush_parent: - ret = bs->file ? bdrv_co_flush(bs->file->bs) : 0; +flush_children: + ret = 0; + QLIST_FOREACH(child, &bs->children, next) { + int this_child_ret; + + this_child_ret = bdrv_co_flush(child->bs); + if (!ret) { + ret = this_child_ret; + } + } + out: /* Notify any pending flushes that we have completed */ if (ret == 0) { From patchwork Fri Aug 9 16:13:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087161 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 C28EB13AC for ; Fri, 9 Aug 2019 16:20:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B1CED1FF73 for ; Fri, 9 Aug 2019 16:20:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A54C8204BA; Fri, 9 Aug 2019 16:20:28 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C9FE020246 for ; Fri, 9 Aug 2019 16:20:27 +0000 (UTC) Received: from localhost ([::1]:60896 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7cm-00064u-VB for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:20:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57187) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7XY-0001jX-1b for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7XX-0004DT-4o for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:51 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58740) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7XV-0004CM-1E; Fri, 09 Aug 2019 12:14:49 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 59FD4757C2; Fri, 9 Aug 2019 16:14:48 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id EA76D5C578; Fri, 9 Aug 2019 16:14:47 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:42 +0200 Message-Id: <20190809161407.11920-18-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Fri, 09 Aug 2019 16:14:48 +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 v6 17/42] block: Use CAFs in bdrv_refresh_limits() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/io.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/block/io.c b/block/io.c index bcc770d336..dca4689b2f 100644 --- a/block/io.c +++ b/block/io.c @@ -135,6 +135,8 @@ static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src) void bdrv_refresh_limits(BlockDriverState *bs, Error **errp) { BlockDriver *drv = bs->drv; + BlockDriverState *storage_bs = bdrv_storage_bs(bs); + BlockDriverState *cow_bs = bdrv_filtered_cow_bs(bs); Error *local_err = NULL; memset(&bs->bl, 0, sizeof(bs->bl)); @@ -148,13 +150,13 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp) drv->bdrv_aio_preadv) ? 1 : 512; /* Take some limits from the children as a default */ - if (bs->file) { - bdrv_refresh_limits(bs->file->bs, &local_err); + if (storage_bs) { + bdrv_refresh_limits(storage_bs, &local_err); if (local_err) { error_propagate(errp, local_err); return; } - bdrv_merge_limits(&bs->bl, &bs->file->bs->bl); + bdrv_merge_limits(&bs->bl, &storage_bs->bl); } else { bs->bl.min_mem_alignment = 512; bs->bl.opt_mem_alignment = getpagesize(); @@ -163,13 +165,13 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp) bs->bl.max_iov = IOV_MAX; } - if (bs->backing) { - bdrv_refresh_limits(bs->backing->bs, &local_err); + if (cow_bs) { + bdrv_refresh_limits(cow_bs, &local_err); if (local_err) { error_propagate(errp, local_err); return; } - bdrv_merge_limits(&bs->bl, &bs->backing->bs->bl); + bdrv_merge_limits(&bs->bl, &cow_bs->bl); } /* Then let the driver override it */ From patchwork Fri Aug 9 16:13:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087209 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 05A6914D5 for ; Fri, 9 Aug 2019 16:21:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E8A522015F for ; Fri, 9 Aug 2019 16:21:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DCCF0201A4; Fri, 9 Aug 2019 16:21:49 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7CB98201BC for ; Fri, 9 Aug 2019 16:21:49 +0000 (UTC) Received: from localhost ([::1]:60934 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7eG-000197-Sf for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:21:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57219) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Xa-0001uG-Rg for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7XZ-0004Ek-Om for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38048) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7XX-0004DN-97; Fri, 09 Aug 2019 12:14:51 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9820D88309; Fri, 9 Aug 2019 16:14:50 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 352035C29A; Fri, 9 Aug 2019 16:14:50 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:43 +0200 Message-Id: <20190809161407.11920-19-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Fri, 09 Aug 2019 16:14:50 +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 v6 18/42] block: Use CAFs in bdrv_refresh_filename() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP bdrv_refresh_filename() and the kind of related bdrv_dirname() should look to the primary child when they wish to copy the underlying file's filename. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/block.c b/block.c index 064cc99857..a467b175c6 100644 --- a/block.c +++ b/block.c @@ -6432,6 +6432,7 @@ void bdrv_refresh_filename(BlockDriverState *bs) { BlockDriver *drv = bs->drv; BdrvChild *child; + BlockDriverState *primary_child_bs; QDict *opts; bool backing_overridden; bool generate_json_filename; /* Whether our default implementation should @@ -6500,20 +6501,30 @@ void bdrv_refresh_filename(BlockDriverState *bs) qobject_unref(bs->full_open_options); bs->full_open_options = opts; + primary_child_bs = bdrv_primary_bs(bs); + if (drv->bdrv_refresh_filename) { /* Obsolete information is of no use here, so drop the old file name * information before refreshing it */ bs->exact_filename[0] = '\0'; drv->bdrv_refresh_filename(bs); - } else if (bs->file) { - /* Try to reconstruct valid information from the underlying file */ + } else if (primary_child_bs) { + /* + * Try to reconstruct valid information from the underlying + * file -- this only works for format nodes (filter nodes + * cannot be probed and as such must be selected by the user + * either through an options dict, or through a special + * filename which the filter driver must construct in its + * .bdrv_refresh_filename() implementation). + */ bs->exact_filename[0] = '\0'; /* * We can use the underlying file's filename if: * - it has a filename, + * - the current BDS is not a filter, * - the file is a protocol BDS, and * - opening that file (as this BDS's format) will automatically create * the BDS tree we have right now, that is: @@ -6522,11 +6533,11 @@ void bdrv_refresh_filename(BlockDriverState *bs) * - no non-file child of this BDS has been overridden by the user * Both of these conditions are represented by generate_json_filename. */ - if (bs->file->bs->exact_filename[0] && - bs->file->bs->drv->bdrv_file_open && - !generate_json_filename) + if (primary_child_bs->exact_filename[0] && + primary_child_bs->drv->bdrv_file_open && + !drv->is_filter && !generate_json_filename) { - strcpy(bs->exact_filename, bs->file->bs->exact_filename); + strcpy(bs->exact_filename, primary_child_bs->exact_filename); } } @@ -6543,6 +6554,7 @@ void bdrv_refresh_filename(BlockDriverState *bs) char *bdrv_dirname(BlockDriverState *bs, Error **errp) { BlockDriver *drv = bs->drv; + BlockDriverState *child_bs; if (!drv) { error_setg(errp, "Node '%s' is ejected", bs->node_name); @@ -6553,8 +6565,9 @@ char *bdrv_dirname(BlockDriverState *bs, Error **errp) return drv->bdrv_dirname(bs, errp); } - if (bs->file) { - return bdrv_dirname(bs->file->bs, errp); + child_bs = bdrv_primary_bs(bs); + if (child_bs) { + return bdrv_dirname(child_bs, errp); } bdrv_refresh_filename(bs); From patchwork Fri Aug 9 16:13:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087259 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 BB97C14D5 for ; Fri, 9 Aug 2019 16:27:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A9A95202A5 for ; Fri, 9 Aug 2019 16:27:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9DE742022B; Fri, 9 Aug 2019 16:27:38 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 5038920243 for ; Fri, 9 Aug 2019 16:27:38 +0000 (UTC) Received: from localhost ([::1]:32815 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7jt-0005nJ-KS for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:27:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57241) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Xc-0001zm-ER for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Xb-0004Fq-Fs for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:14:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58952) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7XZ-0004EQ-Gr; Fri, 09 Aug 2019 12:14:53 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D7CB63078A2E; Fri, 9 Aug 2019 16:14:52 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 75C3660BF7; Fri, 9 Aug 2019 16:14:52 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:44 +0200 Message-Id: <20190809161407.11920-20-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Fri, 09 Aug 2019 16:14:52 +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 v6 19/42] block: Use CAF in bdrv_co_rw_vmstate() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP If a node whose driver does not provide VM state functions has a metadata child, the VM state should probably go there; if it is a filter, the VM state should probably go there. It follows that we should generally go down to the primary child. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/io.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/block/io.c b/block/io.c index dca4689b2f..e222d91893 100644 --- a/block/io.c +++ b/block/io.c @@ -2434,6 +2434,7 @@ bdrv_co_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos, bool is_read) { BlockDriver *drv = bs->drv; + BlockDriverState *child_bs = bdrv_primary_bs(bs); int ret = -ENOTSUP; bdrv_inc_in_flight(bs); @@ -2446,8 +2447,8 @@ bdrv_co_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos, } else { ret = drv->bdrv_save_vmstate(bs, qiov, pos); } - } else if (bs->file) { - ret = bdrv_co_rw_vmstate(bs->file->bs, qiov, pos, is_read); + } else if (child_bs) { + ret = bdrv_co_rw_vmstate(child_bs, qiov, pos, is_read); } bdrv_dec_in_flight(bs); From patchwork Fri Aug 9 16:13:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087269 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 11A3713AC for ; Fri, 9 Aug 2019 16:28:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F320D201F5 for ; Fri, 9 Aug 2019 16:28:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E6C422023F; Fri, 9 Aug 2019 16:28:38 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 58F9020243 for ; Fri, 9 Aug 2019 16:28:38 +0000 (UTC) Received: from localhost ([::1]:32838 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7kr-000190-O9 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:28:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57275) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Xg-0002DF-BI for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Xe-0004HE-Vx for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:00 -0400 Received: from mx1.redhat.com ([209.132.183.28]:14135) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Xb-0004Fn-Vu; Fri, 09 Aug 2019 12:14:56 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4ECB381F07; Fri, 9 Aug 2019 16:14:55 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B36D15C578; Fri, 9 Aug 2019 16:14:54 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:45 +0200 Message-Id: <20190809161407.11920-21-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Fri, 09 Aug 2019 16:14:55 +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 v6 20/42] block/snapshot: Fix fallback X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP If the top node's driver does not provide snapshot functionality and we want to fall back to a node down the chain, we need to snapshot all non-COW children. For simplicity's sake, just do not fall back if there is more than one such child. bdrv_snapshot_goto() becomes a bit weird because we may have to redirect the actual child pointer, so it only works if the fallback child is bs->file or bs->backing (and then we have to find out which it is). Suggested-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Max Reitz --- block/snapshot.c | 100 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 79 insertions(+), 21 deletions(-) diff --git a/block/snapshot.c b/block/snapshot.c index f2f48f926a..35403c167f 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -146,6 +146,32 @@ bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs, return ret; } +/** + * Return the child BDS to which we can fall back if the given BDS + * does not support snapshots. + * Return NULL if there is no BDS to (safely) fall back to. + */ +static BlockDriverState *bdrv_snapshot_fallback(BlockDriverState *bs) +{ + BlockDriverState *child_bs = NULL; + BdrvChild *child; + + QLIST_FOREACH(child, &bs->children, next) { + if (child == bdrv_filtered_cow_child(bs)) { + /* Ignore: COW children need not be included in snapshots */ + continue; + } + + if (child_bs) { + /* Cannot fall back to a single child if there are multiple */ + return NULL; + } + child_bs = child->bs; + } + + return child_bs; +} + int bdrv_can_snapshot(BlockDriverState *bs) { BlockDriver *drv = bs->drv; @@ -154,8 +180,9 @@ int bdrv_can_snapshot(BlockDriverState *bs) } if (!drv->bdrv_snapshot_create) { - if (bs->file != NULL) { - return bdrv_can_snapshot(bs->file->bs); + BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs); + if (fallback_bs) { + return bdrv_can_snapshot(fallback_bs); } return 0; } @@ -167,14 +194,15 @@ int bdrv_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) { BlockDriver *drv = bs->drv; + BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs); if (!drv) { return -ENOMEDIUM; } if (drv->bdrv_snapshot_create) { return drv->bdrv_snapshot_create(bs, sn_info); } - if (bs->file) { - return bdrv_snapshot_create(bs->file->bs, sn_info); + if (fallback_bs) { + return bdrv_snapshot_create(fallback_bs, sn_info); } return -ENOTSUP; } @@ -184,6 +212,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs, Error **errp) { BlockDriver *drv = bs->drv; + BlockDriverState *fallback_bs; int ret, open_ret; if (!drv) { @@ -204,39 +233,66 @@ int bdrv_snapshot_goto(BlockDriverState *bs, return ret; } - if (bs->file) { - BlockDriverState *file; - QDict *options = qdict_clone_shallow(bs->options); + fallback_bs = bdrv_snapshot_fallback(bs); + if (fallback_bs) { + QDict *options; QDict *file_options; Error *local_err = NULL; + bool is_backing_child; + BdrvChild **child_pointer; + + /* + * We need a pointer to the fallback child pointer, so let us + * see whether the child is referenced by a field in the BDS + * object. + */ + if (fallback_bs == bs->file->bs) { + is_backing_child = false; + child_pointer = &bs->file; + } else if (fallback_bs == bs->backing->bs) { + is_backing_child = true; + child_pointer = &bs->backing; + } else { + /* + * The fallback child is not referenced by a field in the + * BDS object. We cannot go on then. + */ + error_setg(errp, "Block driver does not support snapshots"); + return -ENOTSUP; + } + + options = qdict_clone_shallow(bs->options); - file = bs->file->bs; /* Prevent it from getting deleted when detached from bs */ - bdrv_ref(file); + bdrv_ref(fallback_bs); - qdict_extract_subqdict(options, &file_options, "file."); + qdict_extract_subqdict(options, &file_options, + is_backing_child ? "backing." : "file."); qobject_unref(file_options); - qdict_put_str(options, "file", bdrv_get_node_name(file)); + qdict_put_str(options, is_backing_child ? "backing" : "file", + bdrv_get_node_name(fallback_bs)); if (drv->bdrv_close) { drv->bdrv_close(bs); } - bdrv_unref_child(bs, bs->file); - bs->file = NULL; - ret = bdrv_snapshot_goto(file, snapshot_id, errp); + assert(fallback_bs == (*child_pointer)->bs); + bdrv_unref_child(bs, *child_pointer); + *child_pointer = NULL; + + ret = bdrv_snapshot_goto(fallback_bs, snapshot_id, errp); open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err); qobject_unref(options); if (open_ret < 0) { - bdrv_unref(file); + bdrv_unref(fallback_bs); bs->drv = NULL; /* A bdrv_snapshot_goto() error takes precedence */ error_propagate(errp, local_err); return ret < 0 ? ret : open_ret; } - assert(bs->file->bs == file); - bdrv_unref(file); + assert(fallback_bs == (*child_pointer)->bs); + bdrv_unref(fallback_bs); return ret; } @@ -272,6 +328,7 @@ int bdrv_snapshot_delete(BlockDriverState *bs, Error **errp) { BlockDriver *drv = bs->drv; + BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs); int ret; if (!drv) { @@ -288,8 +345,8 @@ int bdrv_snapshot_delete(BlockDriverState *bs, if (drv->bdrv_snapshot_delete) { ret = drv->bdrv_snapshot_delete(bs, snapshot_id, name, errp); - } else if (bs->file) { - ret = bdrv_snapshot_delete(bs->file->bs, snapshot_id, name, errp); + } else if (fallback_bs) { + ret = bdrv_snapshot_delete(fallback_bs, snapshot_id, name, errp); } else { error_setg(errp, "Block format '%s' used by device '%s' " "does not support internal snapshot deletion", @@ -305,14 +362,15 @@ int bdrv_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_info) { BlockDriver *drv = bs->drv; + BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs); if (!drv) { return -ENOMEDIUM; } if (drv->bdrv_snapshot_list) { return drv->bdrv_snapshot_list(bs, psn_info); } - if (bs->file) { - return bdrv_snapshot_list(bs->file->bs, psn_info); + if (fallback_bs) { + return bdrv_snapshot_list(fallback_bs, psn_info); } return -ENOTSUP; } From patchwork Fri Aug 9 16:13:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087147 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 4C25014D5 for ; Fri, 9 Aug 2019 16:19:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 37AF61FF87 for ; Fri, 9 Aug 2019 16:19:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2B96E2022B; Fri, 9 Aug 2019 16:19:59 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 77F16201F3 for ; Fri, 9 Aug 2019 16:19:57 +0000 (UTC) Received: from localhost ([::1]:60893 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7cS-0004yn-MR for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:19:56 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57290) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Xh-0002Gx-D8 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Xg-0004IK-Bv for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:01 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58998) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Xe-0004Gq-8N; Fri, 09 Aug 2019 12:14:58 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 91657309E5B4; Fri, 9 Aug 2019 16:14:57 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2D7CC608C2; Fri, 9 Aug 2019 16:14:57 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:46 +0200 Message-Id: <20190809161407.11920-22-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Fri, 09 Aug 2019 16:14:57 +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 v6 21/42] block: Use CAFs for debug breakpoints X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP When looking for a blkdebug node (which implements debug breakpoints), use bdrv_primary_bs() to iterate through the graph, because that is where a blkdebug node would be. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block.c b/block.c index a467b175c6..1070aa1ba9 100644 --- a/block.c +++ b/block.c @@ -5218,7 +5218,7 @@ int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, const char *tag) { while (bs && bs->drv && !bs->drv->bdrv_debug_breakpoint) { - bs = bs->file ? bs->file->bs : NULL; + bs = bdrv_primary_bs(bs); } if (bs && bs->drv && bs->drv->bdrv_debug_breakpoint) { @@ -5231,7 +5231,7 @@ int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag) { while (bs && bs->drv && !bs->drv->bdrv_debug_remove_breakpoint) { - bs = bs->file ? bs->file->bs : NULL; + bs = bdrv_primary_bs(bs); } if (bs && bs->drv && bs->drv->bdrv_debug_remove_breakpoint) { @@ -5244,7 +5244,7 @@ int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag) int bdrv_debug_resume(BlockDriverState *bs, const char *tag) { while (bs && (!bs->drv || !bs->drv->bdrv_debug_resume)) { - bs = bs->file ? bs->file->bs : NULL; + bs = bdrv_primary_bs(bs); } if (bs && bs->drv && bs->drv->bdrv_debug_resume) { @@ -5257,7 +5257,7 @@ int bdrv_debug_resume(BlockDriverState *bs, const char *tag) bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag) { while (bs && bs->drv && !bs->drv->bdrv_debug_is_suspended) { - bs = bs->file ? bs->file->bs : NULL; + bs = bdrv_primary_bs(bs); } if (bs && bs->drv && bs->drv->bdrv_debug_is_suspended) { From patchwork Fri Aug 9 16:13:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087207 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 8162613AC for ; Fri, 9 Aug 2019 16:21:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 709CA20069 for ; Fri, 9 Aug 2019 16:21:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 64B2F2015F; Fri, 9 Aug 2019 16:21:20 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 14A1020069 for ; Fri, 9 Aug 2019 16:21:20 +0000 (UTC) Received: from localhost ([::1]:60930 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7dn-0008Uv-Fa for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:21:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57327) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Xj-0002P6-Q5 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Xi-0004JR-Oj for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44832) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Xg-0004I5-Hk; Fri, 09 Aug 2019 12:15:00 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D62ED30BE7DB; Fri, 9 Aug 2019 16:14:59 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6D58C600CD; Fri, 9 Aug 2019 16:14:59 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:47 +0200 Message-Id: <20190809161407.11920-23-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Fri, 09 Aug 2019 16:14:59 +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 v6 22/42] block: Fix bdrv_get_allocated_file_size's fallback X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP If the driver does not implement bdrv_get_allocated_file_size(), we should fall back to cumulating the allocated size of all non-COW children instead of just bs->file. Suggested-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index 1070aa1ba9..6e1ddab056 100644 --- a/block.c +++ b/block.c @@ -4650,9 +4650,27 @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs) if (drv->bdrv_get_allocated_file_size) { return drv->bdrv_get_allocated_file_size(bs); } - if (bs->file) { - return bdrv_get_allocated_file_size(bs->file->bs); + + if (!QLIST_EMPTY(&bs->children)) { + BdrvChild *child; + int64_t child_size, total_size = 0; + + QLIST_FOREACH(child, &bs->children, next) { + if (child == bdrv_filtered_cow_child(bs)) { + /* Ignore COW backing files */ + continue; + } + + child_size = bdrv_get_allocated_file_size(child->bs); + if (child_size < 0) { + return child_size; + } + total_size += child_size; + } + + return total_size; } + return -ENOTSUP; } From patchwork Fri Aug 9 16:13:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087215 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 CFE5614D5 for ; Fri, 9 Aug 2019 16:22:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BE77B2012F for ; Fri, 9 Aug 2019 16:22:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B2963201B1; Fri, 9 Aug 2019 16:22:35 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 5DD9E2012F for ; Fri, 9 Aug 2019 16:22:35 +0000 (UTC) Received: from localhost ([::1]:60960 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7f0-0003fa-Nz for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:22:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57345) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Xl-0002VM-OR for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Xk-0004LH-SX for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:05 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59044) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Xi-0004JH-RS; Fri, 09 Aug 2019 12:15:02 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1FC423090FD9; Fri, 9 Aug 2019 16:15:02 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id ABFDF7E44; Fri, 9 Aug 2019 16:15:01 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:48 +0200 Message-Id: <20190809161407.11920-24-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Fri, 09 Aug 2019 16:15:02 +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 v6 23/42] blockdev: Use CAF in external_snapshot_prepare() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This allows us to differentiate between filters and nodes with COW backing files: Filters cannot be used as overlays at all (for this function). Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- blockdev.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/blockdev.c b/blockdev.c index 29c6c6044a..c540802127 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1664,7 +1664,12 @@ static void external_snapshot_prepare(BlkActionState *common, goto out; } - if (state->new_bs->backing != NULL) { + if (state->new_bs->drv->is_filter) { + error_setg(errp, "Filters cannot be used as overlays"); + goto out; + } + + if (bdrv_filtered_cow_child(state->new_bs)) { error_setg(errp, "The overlay already has a backing image"); goto out; } From patchwork Fri Aug 9 16:13:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087217 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 35BB113AC for ; Fri, 9 Aug 2019 16:23:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 235301FF87 for ; Fri, 9 Aug 2019 16:23:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 17BBB201BC; Fri, 9 Aug 2019 16:23:06 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9E3591FF87 for ; Fri, 9 Aug 2019 16:23:05 +0000 (UTC) Received: from localhost ([::1]:60964 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7fV-0004Yg-0n for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:23:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57372) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Xr-0002oB-3O for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Xp-0004P3-Tu for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:11 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53650) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Xn-0004M5-B3; Fri, 09 Aug 2019 12:15:07 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A42A8309BF22; Fri, 9 Aug 2019 16:15:06 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0FDAD6D09D; Fri, 9 Aug 2019 16:15:03 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:49 +0200 Message-Id: <20190809161407.11920-25-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Fri, 09 Aug 2019 16:15:06 +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 v6 24/42] block: Use child access functions for QAPI queries X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP query-block, query-named-block-nodes, and query-blockstats now return any filtered child under "backing", not just bs->backing or COW children. This is so that filters do not interrupt the reported backing chain. This changes the output for iotest 184, as the throttled node now appears as a backing child. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/qapi.c | 39 +++++++++++++++++++++++--------------- tests/qemu-iotests/184.out | 7 ++++++- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/block/qapi.c b/block/qapi.c index 9a185cba48..4f59ac1c0f 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -156,9 +156,13 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk, return NULL; } - if (bs0->drv && bs0->backing) { + if (bs0->drv && bdrv_filtered_child(bs0)) { + /* + * Put any filtered child here (for backwards compatibility to when + * we put bs0->backing here, which might be any filtered child). + */ info->backing_file_depth++; - bs0 = bs0->backing->bs; + bs0 = bdrv_filtered_bs(bs0); (*p_image_info)->has_backing_image = true; p_image_info = &((*p_image_info)->backing_image); } else { @@ -167,9 +171,8 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk, /* Skip automatically inserted nodes that the user isn't aware of for * query-block (blk != NULL), but not for query-named-block-nodes */ - while (blk && bs0->drv && bs0->implicit) { - bs0 = backing_bs(bs0); - assert(bs0); + if (blk) { + bs0 = bdrv_skip_implicit_filters(bs0); } } @@ -354,9 +357,9 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info, BlockDriverState *bs = blk_bs(blk); char *qdev; - /* Skip automatically inserted nodes that the user isn't aware of */ - while (bs && bs->drv && bs->implicit) { - bs = backing_bs(bs); + if (bs) { + /* Skip automatically inserted nodes that the user isn't aware of */ + bs = bdrv_skip_implicit_filters(bs); } info->device = g_strdup(blk_name(blk)); @@ -513,6 +516,7 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk) static BlockStats *bdrv_query_bds_stats(BlockDriverState *bs, bool blk_level) { + BlockDriverState *storage_bs, *filtered_bs; BlockStats *s = NULL; s = g_malloc0(sizeof(*s)); @@ -525,9 +529,8 @@ static BlockStats *bdrv_query_bds_stats(BlockDriverState *bs, /* Skip automatically inserted nodes that the user isn't aware of in * a BlockBackend-level command. Stay at the exact node for a node-level * command. */ - while (blk_level && bs->drv && bs->implicit) { - bs = backing_bs(bs); - assert(bs); + if (blk_level) { + bs = bdrv_skip_implicit_filters(bs); } if (bdrv_get_node_name(bs)[0]) { @@ -537,14 +540,20 @@ static BlockStats *bdrv_query_bds_stats(BlockDriverState *bs, s->stats->wr_highest_offset = stat64_get(&bs->wr_highest_offset); - if (bs->file) { + storage_bs = bdrv_storage_bs(bs); + if (storage_bs) { s->has_parent = true; - s->parent = bdrv_query_bds_stats(bs->file->bs, blk_level); + s->parent = bdrv_query_bds_stats(storage_bs, blk_level); } - if (blk_level && bs->backing) { + filtered_bs = bdrv_filtered_bs(bs); + if (blk_level && filtered_bs) { + /* + * Put any filtered child here (for backwards compatibility to when + * we put bs0->backing here, which might be any filtered child). + */ s->has_backing = true; - s->backing = bdrv_query_bds_stats(bs->backing->bs, blk_level); + s->backing = bdrv_query_bds_stats(filtered_bs, blk_level); } return s; diff --git a/tests/qemu-iotests/184.out b/tests/qemu-iotests/184.out index 3deb3cfb94..1d61f7e224 100644 --- a/tests/qemu-iotests/184.out +++ b/tests/qemu-iotests/184.out @@ -27,6 +27,11 @@ Testing: "iops_rd": 0, "detect_zeroes": "off", "image": { + "backing-image": { + "virtual-size": 1073741824, + "filename": "null-co://", + "format": "null-co" + }, "virtual-size": 1073741824, "filename": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"null-co\"}}", "format": "throttle" @@ -34,7 +39,7 @@ Testing: "iops_wr": 0, "ro": false, "node-name": "throttle0", - "backing_file_depth": 0, + "backing_file_depth": 1, "drv": "throttle", "iops": 0, "bps_wr": 0, From patchwork Fri Aug 9 16:13:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087247 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 362FF14D5 for ; Fri, 9 Aug 2019 16:26:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 240F220069 for ; Fri, 9 Aug 2019 16:26:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 186E8201F5; Fri, 9 Aug 2019 16:26:42 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2DE1B20069 for ; Fri, 9 Aug 2019 16:26:41 +0000 (UTC) Received: from localhost ([::1]:32792 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7iy-0003F2-IH for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:26:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57430) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Xw-00034R-13 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Xu-0004Sc-3U for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51408) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Xp-0004Nv-Qv; Fri, 09 Aug 2019 12:15:10 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 202E5316EFEC; Fri, 9 Aug 2019 16:15:09 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 808635C29A; Fri, 9 Aug 2019 16:15:08 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:50 +0200 Message-Id: <20190809161407.11920-26-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Fri, 09 Aug 2019 16:15:09 +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 v6 25/42] mirror: Deal with filters X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This includes some permission limiting (for example, we only need to take the RESIZE permission for active commits where the base is smaller than the top). Signed-off-by: Max Reitz --- block/mirror.c | 117 ++++++++++++++++++++++++++++++++++++++----------- blockdev.c | 47 +++++++++++++++++--- 2 files changed, 131 insertions(+), 33 deletions(-) diff --git a/block/mirror.c b/block/mirror.c index 54bafdf176..6ddbfb9708 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -42,6 +42,7 @@ typedef struct MirrorBlockJob { BlockBackend *target; BlockDriverState *mirror_top_bs; BlockDriverState *base; + BlockDriverState *base_overlay; /* The name of the graph node to replace */ char *replaces; @@ -665,8 +666,10 @@ static int mirror_exit_common(Job *job) &error_abort); if (!abort && s->backing_mode == MIRROR_SOURCE_BACKING_CHAIN) { BlockDriverState *backing = s->is_none_mode ? src : s->base; - if (backing_bs(target_bs) != backing) { - bdrv_set_backing_hd(target_bs, backing, &local_err); + BlockDriverState *unfiltered_target = bdrv_skip_rw_filters(target_bs); + + if (bdrv_filtered_cow_bs(unfiltered_target) != backing) { + bdrv_set_backing_hd(unfiltered_target, backing, &local_err); if (local_err) { error_report_err(local_err); ret = -EPERM; @@ -715,7 +718,7 @@ static int mirror_exit_common(Job *job) * valid. */ block_job_remove_all_bdrv(bjob); - bdrv_replace_node(mirror_top_bs, backing_bs(mirror_top_bs), &error_abort); + bdrv_replace_node(mirror_top_bs, mirror_top_bs->backing->bs, &error_abort); /* We just changed the BDS the job BB refers to (with either or both of the * bdrv_replace_node() calls), so switch the BB back so the cleanup does @@ -812,7 +815,8 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s) return 0; } - ret = bdrv_is_allocated_above(bs, base, false, offset, bytes, &count); + ret = bdrv_is_allocated_above(bs, s->base_overlay, true, offset, bytes, + &count); if (ret < 0) { return ret; } @@ -908,7 +912,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp) } else { s->target_cluster_size = BDRV_SECTOR_SIZE; } - if (backing_filename[0] && !target_bs->backing && + if (backing_filename[0] && !bdrv_backing_chain_next(target_bs) && s->granularity < s->target_cluster_size) { s->buf_size = MAX(s->buf_size, s->target_cluster_size); s->cow_bitmap = bitmap_new(length); @@ -1088,8 +1092,9 @@ static void mirror_complete(Job *job, Error **errp) if (s->backing_mode == MIRROR_OPEN_BACKING_CHAIN) { int ret; - assert(!target->backing); - ret = bdrv_open_backing_file(target, NULL, "backing", errp); + assert(!bdrv_backing_chain_next(target)); + ret = bdrv_open_backing_file(bdrv_skip_rw_filters(target), NULL, + "backing", errp); if (ret < 0) { return; } @@ -1531,8 +1536,8 @@ static BlockJob *mirror_start_job( MirrorBlockJob *s; MirrorBDSOpaque *bs_opaque; BlockDriverState *mirror_top_bs; - bool target_graph_mod; bool target_is_backing; + uint64_t target_perms, target_shared_perms; Error *local_err = NULL; int ret; @@ -1551,7 +1556,7 @@ static BlockJob *mirror_start_job( buf_size = DEFAULT_MIRROR_BUF_SIZE; } - if (bs == target) { + if (bdrv_skip_rw_filters(bs) == bdrv_skip_rw_filters(target)) { error_setg(errp, "Can't mirror node into itself"); return NULL; } @@ -1615,15 +1620,50 @@ static BlockJob *mirror_start_job( * In the case of active commit, things look a bit different, though, * because the target is an already populated backing file in active use. * We can allow anything except resize there.*/ + + target_perms = BLK_PERM_WRITE; + target_shared_perms = BLK_PERM_WRITE_UNCHANGED; + target_is_backing = bdrv_chain_contains(bs, target); - target_graph_mod = (backing_mode != MIRROR_LEAVE_BACKING_CHAIN); + if (target_is_backing) { + int64_t bs_size, target_size; + bs_size = bdrv_getlength(bs); + if (bs_size < 0) { + error_setg_errno(errp, -bs_size, + "Could not inquire top image size"); + goto fail; + } + + target_size = bdrv_getlength(target); + if (target_size < 0) { + error_setg_errno(errp, -target_size, + "Could not inquire base image size"); + goto fail; + } + + if (target_size < bs_size) { + target_perms |= BLK_PERM_RESIZE; + } + + target_shared_perms |= BLK_PERM_CONSISTENT_READ + | BLK_PERM_WRITE + | BLK_PERM_GRAPH_MOD; + } else if (bdrv_chain_contains(bs, bdrv_skip_rw_filters(target))) { + /* + * We may want to allow this in the future, but it would + * require taking some extra care. + */ + error_setg(errp, "Cannot mirror to a filter on top of a node in the " + "source's backing chain"); + goto fail; + } + + if (backing_mode != MIRROR_LEAVE_BACKING_CHAIN) { + target_perms |= BLK_PERM_GRAPH_MOD; + } + s->target = blk_new(s->common.job.aio_context, - BLK_PERM_WRITE | BLK_PERM_RESIZE | - (target_graph_mod ? BLK_PERM_GRAPH_MOD : 0), - BLK_PERM_WRITE_UNCHANGED | - (target_is_backing ? BLK_PERM_CONSISTENT_READ | - BLK_PERM_WRITE | - BLK_PERM_GRAPH_MOD : 0)); + target_perms, target_shared_perms); ret = blk_insert_bs(s->target, target, errp); if (ret < 0) { goto fail; @@ -1647,6 +1687,7 @@ static BlockJob *mirror_start_job( s->backing_mode = backing_mode; s->copy_mode = copy_mode; s->base = base; + s->base_overlay = bdrv_find_overlay(bs, base); s->granularity = granularity; s->buf_size = ROUND_UP(buf_size, granularity); s->unmap = unmap; @@ -1693,15 +1734,39 @@ static BlockJob *mirror_start_job( /* In commit_active_start() all intermediate nodes disappear, so * any jobs in them must be blocked */ if (target_is_backing) { - BlockDriverState *iter; - for (iter = backing_bs(bs); iter != target; iter = backing_bs(iter)) { - /* XXX BLK_PERM_WRITE needs to be allowed so we don't block - * ourselves at s->base (if writes are blocked for a node, they are - * also blocked for its backing file). The other options would be a - * second filter driver above s->base (== target). */ + BlockDriverState *iter, *filtered_target; + uint64_t iter_shared_perms; + + /* + * The topmost node with + * bdrv_skip_rw_filters(filtered_target) == bdrv_skip_rw_filters(target) + */ + filtered_target = bdrv_filtered_cow_bs(bdrv_find_overlay(bs, target)); + + assert(bdrv_skip_rw_filters(filtered_target) == + bdrv_skip_rw_filters(target)); + + /* + * XXX BLK_PERM_WRITE needs to be allowed so we don't block + * ourselves at s->base (if writes are blocked for a node, they are + * also blocked for its backing file). The other options would be a + * second filter driver above s->base (== target). + */ + iter_shared_perms = BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE; + + for (iter = bdrv_filtered_bs(bs); iter != target; + iter = bdrv_filtered_bs(iter)) + { + if (iter == filtered_target) { + /* + * From here on, all nodes are filters on the base. + * This allows us to share BLK_PERM_CONSISTENT_READ. + */ + iter_shared_perms |= BLK_PERM_CONSISTENT_READ; + } + ret = block_job_add_bdrv(&s->common, "intermediate node", iter, 0, - BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE, - errp); + iter_shared_perms, errp); if (ret < 0) { goto fail; } @@ -1737,7 +1802,7 @@ fail: bs_opaque->stop = true; bdrv_child_refresh_perms(mirror_top_bs, mirror_top_bs->backing, &error_abort); - bdrv_replace_node(mirror_top_bs, backing_bs(mirror_top_bs), &error_abort); + bdrv_replace_node(mirror_top_bs, mirror_top_bs->backing->bs, &error_abort); bdrv_unref(mirror_top_bs); @@ -1764,7 +1829,7 @@ void mirror_start(const char *job_id, BlockDriverState *bs, return; } is_none_mode = mode == MIRROR_SYNC_MODE_NONE; - base = mode == MIRROR_SYNC_MODE_TOP ? backing_bs(bs) : NULL; + base = mode == MIRROR_SYNC_MODE_TOP ? bdrv_backing_chain_next(bs) : NULL; mirror_start_job(job_id, bs, creation_flags, target, replaces, speed, granularity, buf_size, backing_mode, on_source_error, on_target_error, unmap, NULL, NULL, diff --git a/blockdev.c b/blockdev.c index c540802127..c451f553f7 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3851,7 +3851,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, return; } - if (!bs->backing && sync == MIRROR_SYNC_MODE_TOP) { + if (!bdrv_backing_chain_next(bs) && sync == MIRROR_SYNC_MODE_TOP) { sync = MIRROR_SYNC_MODE_FULL; } @@ -3900,7 +3900,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, void qmp_drive_mirror(DriveMirror *arg, Error **errp) { - BlockDriverState *bs; + BlockDriverState *bs, *unfiltered_bs; BlockDriverState *source, *target_bs; AioContext *aio_context; BlockMirrorBackingMode backing_mode; @@ -3909,6 +3909,7 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) int flags; int64_t size; const char *format = arg->format; + const char *replaces_node_name = NULL; int ret; bs = qmp_get_root_bs(arg->device, errp); @@ -3921,6 +3922,16 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) return; } + /* + * If the user has not instructed us otherwise, we should let the + * block job run from @bs (thus taking into account all filters on + * it) but replace @unfiltered_bs when it finishes (thus not + * removing those filters). + * (And if there are any explicit filters, we should assume the + * user knows how to use the @replaces option.) + */ + unfiltered_bs = bdrv_skip_implicit_filters(bs); + aio_context = bdrv_get_aio_context(bs); aio_context_acquire(aio_context); @@ -3934,8 +3945,14 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) } flags = bs->open_flags | BDRV_O_RDWR; - source = backing_bs(bs); + source = bdrv_filtered_cow_bs(unfiltered_bs); if (!source && arg->sync == MIRROR_SYNC_MODE_TOP) { + if (bdrv_filtered_bs(unfiltered_bs)) { + /* @unfiltered_bs is an explicit filter */ + error_setg(errp, "Cannot perform sync=top mirror through an " + "explicitly added filter node on the source"); + goto out; + } arg->sync = MIRROR_SYNC_MODE_FULL; } if (arg->sync == MIRROR_SYNC_MODE_NONE) { @@ -3954,6 +3971,9 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) " named node of the graph"); goto out; } + replaces_node_name = arg->replaces; + } else if (unfiltered_bs != bs) { + replaces_node_name = unfiltered_bs->node_name; } if (arg->mode == NEW_IMAGE_MODE_ABSOLUTE_PATHS) { @@ -3973,6 +3993,9 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) bdrv_img_create(arg->target, format, NULL, NULL, NULL, size, flags, false, &local_err); } else { + /* Implicit filters should not appear in the filename */ + BlockDriverState *explicit_backing = bdrv_skip_implicit_filters(source); + switch (arg->mode) { case NEW_IMAGE_MODE_EXISTING: break; @@ -3980,8 +4003,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) /* create new image with backing file */ bdrv_refresh_filename(source); bdrv_img_create(arg->target, format, - source->filename, - source->drv->format_name, + explicit_backing->filename, + explicit_backing->drv->format_name, NULL, size, flags, false, &local_err); break; default: @@ -4017,7 +4040,7 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) } blockdev_mirror_common(arg->has_job_id ? arg->job_id : NULL, bs, target_bs, - arg->has_replaces, arg->replaces, arg->sync, + !!replaces_node_name, replaces_node_name, arg->sync, backing_mode, arg->has_speed, arg->speed, arg->has_granularity, arg->granularity, arg->has_buf_size, arg->buf_size, @@ -4053,7 +4076,7 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id, bool has_auto_dismiss, bool auto_dismiss, Error **errp) { - BlockDriverState *bs; + BlockDriverState *bs, *unfiltered_bs; BlockDriverState *target_bs; AioContext *aio_context; BlockMirrorBackingMode backing_mode = MIRROR_LEAVE_BACKING_CHAIN; @@ -4065,6 +4088,16 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id, return; } + /* + * Same as in qmp_drive_mirror(): We want to run the job from @bs, + * but we want to replace @unfiltered_bs on completion. + */ + unfiltered_bs = bdrv_skip_implicit_filters(bs); + if (!has_replaces && unfiltered_bs != bs) { + replaces = unfiltered_bs->node_name; + has_replaces = true; + } + target_bs = bdrv_lookup_bs(target, target, errp); if (!target_bs) { return; From patchwork Fri Aug 9 16:13:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087231 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 9FBE813AC for ; Fri, 9 Aug 2019 16:24:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8EB341FF73 for ; Fri, 9 Aug 2019 16:24:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 83928201F5; Fri, 9 Aug 2019 16:24:40 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id BD2292012F for ; Fri, 9 Aug 2019 16:24:39 +0000 (UTC) Received: from localhost ([::1]:60992 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7h1-0007Zu-3k for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:24:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57429) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Xw-00034O-25 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Xu-0004T1-PA for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59142) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Xs-0004R6-46; Fri, 09 Aug 2019 12:15:12 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 69F1B30A00E6; Fri, 9 Aug 2019 16:15:11 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id F2B0A60BF7; Fri, 9 Aug 2019 16:15:10 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:51 +0200 Message-Id: <20190809161407.11920-27-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Fri, 09 Aug 2019 16:15:11 +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 v6 26/42] backup: Deal with filters X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/backup.c | 9 +++++---- blockdev.c | 19 +++++++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/block/backup.c b/block/backup.c index ecadb61af3..7854d7575b 100644 --- a/block/backup.c +++ b/block/backup.c @@ -611,6 +611,7 @@ static int64_t backup_calculate_cluster_size(BlockDriverState *target, { int ret; BlockDriverInfo bdi; + bool target_does_cow = bdrv_backing_chain_next(target); /* * If there is no backing file on the target, we cannot rely on COW if our @@ -618,7 +619,7 @@ static int64_t backup_calculate_cluster_size(BlockDriverState *target, * targets with a backing file, try to avoid COW if possible. */ ret = bdrv_get_info(target, &bdi); - if (ret == -ENOTSUP && !target->backing) { + if (ret == -ENOTSUP && !target_does_cow) { /* Cluster size is not defined */ warn_report("The target block device doesn't provide " "information about the block size and it doesn't have a " @@ -627,14 +628,14 @@ static int64_t backup_calculate_cluster_size(BlockDriverState *target, "this default, the backup may be unusable", BACKUP_CLUSTER_SIZE_DEFAULT); return BACKUP_CLUSTER_SIZE_DEFAULT; - } else if (ret < 0 && !target->backing) { + } else if (ret < 0 && !target_does_cow) { error_setg_errno(errp, -ret, "Couldn't determine the cluster size of the target image, " "which has no backing file"); error_append_hint(errp, "Aborting, since this may create an unusable destination image\n"); return ret; - } else if (ret < 0 && target->backing) { + } else if (ret < 0 && target_does_cow) { /* Not fatal; just trudge on ahead. */ return BACKUP_CLUSTER_SIZE_DEFAULT; } @@ -683,7 +684,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, return NULL; } - if (compress && target->drv->bdrv_co_pwritev_compressed == NULL) { + if (compress && !bdrv_supports_compressed_writes(target)) { error_setg(errp, "Compression is not supported for this drive %s", bdrv_get_device_name(target)); return NULL; diff --git a/blockdev.c b/blockdev.c index c451f553f7..c6f79b4e0e 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3656,7 +3656,13 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn, /* See if we have a backing HD we can use to create our new image * on top of. */ if (backup->sync == MIRROR_SYNC_MODE_TOP) { - source = backing_bs(bs); + /* + * Backup will not replace the source by the target, so none + * of the filters skipped here will be removed (in contrast to + * mirror). Therefore, we can skip all of them when looking + * for the first COW relationship. + */ + source = bdrv_filtered_cow_bs(bdrv_skip_rw_filters(bs)); if (!source) { backup->sync = MIRROR_SYNC_MODE_FULL; } @@ -3676,9 +3682,14 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn, if (backup->mode != NEW_IMAGE_MODE_EXISTING) { assert(backup->format); if (source) { - bdrv_refresh_filename(source); - bdrv_img_create(backup->target, backup->format, source->filename, - source->drv->format_name, NULL, + /* Implicit filters should not appear in the filename */ + BlockDriverState *explicit_backing = + bdrv_skip_implicit_filters(source); + + bdrv_refresh_filename(explicit_backing); + bdrv_img_create(backup->target, backup->format, + explicit_backing->filename, + explicit_backing->drv->format_name, NULL, size, flags, false, &local_err); } else { bdrv_img_create(backup->target, backup->format, NULL, NULL, NULL, From patchwork Fri Aug 9 16:13:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087211 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 05B8613AC for ; Fri, 9 Aug 2019 16:22:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E72C320069 for ; Fri, 9 Aug 2019 16:22:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DB0B6201BC; Fri, 9 Aug 2019 16:22:00 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4061C201A4 for ; Fri, 9 Aug 2019 16:22:00 +0000 (UTC) Received: from localhost ([::1]:60940 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7eR-0001jO-LC for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:21:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57483) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Y1-0003LR-1O for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Xz-0004VW-EX for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:20 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59190) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Xv-0004TP-RY; Fri, 09 Aug 2019 12:15:16 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1F08030A00AB; Fri, 9 Aug 2019 16:15:15 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3D296600CC; Fri, 9 Aug 2019 16:15:13 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:52 +0200 Message-Id: <20190809161407.11920-28-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Fri, 09 Aug 2019 16:15:15 +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 v6 27/42] commit: Deal with filters X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This includes some permission limiting (for example, we only need to take the RESIZE permission if the base is smaller than the top). Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/block-backend.c | 16 +++++--- block/commit.c | 96 +++++++++++++++++++++++++++++++------------ blockdev.c | 6 ++- 3 files changed, 85 insertions(+), 33 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index c13c5c83b0..0bc592d023 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -2180,11 +2180,17 @@ int blk_commit_all(void) AioContext *aio_context = blk_get_aio_context(blk); aio_context_acquire(aio_context); - if (blk_is_inserted(blk) && blk->root->bs->backing) { - int ret = bdrv_commit(blk->root->bs); - if (ret < 0) { - aio_context_release(aio_context); - return ret; + if (blk_is_inserted(blk)) { + BlockDriverState *non_filter; + + /* Legacy function, so skip implicit filters */ + non_filter = bdrv_skip_implicit_filters(blk->root->bs); + if (bdrv_filtered_cow_child(non_filter)) { + int ret = bdrv_commit(non_filter); + if (ret < 0) { + aio_context_release(aio_context); + return ret; + } } } aio_context_release(aio_context); diff --git a/block/commit.c b/block/commit.c index 5a7672c7c7..40d1c8eeac 100644 --- a/block/commit.c +++ b/block/commit.c @@ -37,6 +37,7 @@ typedef struct CommitBlockJob { BlockBackend *top; BlockBackend *base; BlockDriverState *base_bs; + BlockDriverState *above_base; BlockdevOnError on_error; bool base_read_only; bool chain_frozen; @@ -110,7 +111,7 @@ static void commit_abort(Job *job) * XXX Can (or should) we somehow keep 'consistent read' blocked even * after the failed/cancelled commit job is gone? If we already wrote * something to base, the intermediate images aren't valid any more. */ - bdrv_replace_node(s->commit_top_bs, backing_bs(s->commit_top_bs), + bdrv_replace_node(s->commit_top_bs, s->commit_top_bs->backing->bs, &error_abort); bdrv_unref(s->commit_top_bs); @@ -174,7 +175,7 @@ static int coroutine_fn commit_run(Job *job, Error **errp) break; } /* Copy if allocated above the base */ - ret = bdrv_is_allocated_above(blk_bs(s->top), blk_bs(s->base), false, + ret = bdrv_is_allocated_above(blk_bs(s->top), s->above_base, true, offset, COMMIT_BUFFER_SIZE, &n); copy = (ret == 1); trace_commit_one_iteration(s, offset, n, ret); @@ -267,15 +268,35 @@ void commit_start(const char *job_id, BlockDriverState *bs, CommitBlockJob *s; BlockDriverState *iter; BlockDriverState *commit_top_bs = NULL; + BlockDriverState *filtered_base; Error *local_err = NULL; + int64_t base_size, top_size; + uint64_t perms, iter_shared_perms; int ret; assert(top != bs); - if (top == base) { + if (bdrv_skip_rw_filters(top) == bdrv_skip_rw_filters(base)) { error_setg(errp, "Invalid files for merge: top and base are the same"); return; } + base_size = bdrv_getlength(base); + if (base_size < 0) { + error_setg_errno(errp, -base_size, "Could not inquire base image size"); + return; + } + + top_size = bdrv_getlength(top); + if (top_size < 0) { + error_setg_errno(errp, -top_size, "Could not inquire top image size"); + return; + } + + perms = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE; + if (base_size < top_size) { + perms |= BLK_PERM_RESIZE; + } + s = block_job_create(job_id, &commit_job_driver, NULL, bs, 0, BLK_PERM_ALL, speed, creation_flags, NULL, NULL, errp); if (!s) { @@ -315,17 +336,43 @@ void commit_start(const char *job_id, BlockDriverState *bs, s->commit_top_bs = commit_top_bs; - /* Block all nodes between top and base, because they will - * disappear from the chain after this operation. */ - assert(bdrv_chain_contains(top, base)); - for (iter = top; iter != base; iter = backing_bs(iter)) { - /* XXX BLK_PERM_WRITE needs to be allowed so we don't block ourselves - * at s->base (if writes are blocked for a node, they are also blocked - * for its backing file). The other options would be a second filter - * driver above s->base. */ + /* + * Block all nodes between top and base, because they will + * disappear from the chain after this operation. + * Note that this assumes that the user is fine with removing all + * nodes (including R/W filters) between top and base. Assuring + * this is the responsibility of the interface (i.e. whoever calls + * commit_start()). + */ + s->above_base = bdrv_find_overlay(top, base); + assert(s->above_base); + + /* + * The topmost node with + * bdrv_skip_rw_filters(filtered_base) == bdrv_skip_rw_filters(base) + */ + filtered_base = bdrv_filtered_cow_bs(s->above_base); + assert(bdrv_skip_rw_filters(filtered_base) == bdrv_skip_rw_filters(base)); + + /* + * XXX BLK_PERM_WRITE needs to be allowed so we don't block ourselves + * at s->base (if writes are blocked for a node, they are also blocked + * for its backing file). The other options would be a second filter + * driver above s->base. + */ + iter_shared_perms = BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE; + + for (iter = top; iter != base; iter = bdrv_filtered_bs(iter)) { + if (iter == filtered_base) { + /* + * From here on, all nodes are filters on the base. This + * allows us to share BLK_PERM_CONSISTENT_READ. + */ + iter_shared_perms |= BLK_PERM_CONSISTENT_READ; + } + ret = block_job_add_bdrv(&s->common, "intermediate node", iter, 0, - BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE, - errp); + iter_shared_perms, errp); if (ret < 0) { goto fail; } @@ -342,9 +389,7 @@ void commit_start(const char *job_id, BlockDriverState *bs, } s->base = blk_new(s->common.job.aio_context, - BLK_PERM_CONSISTENT_READ - | BLK_PERM_WRITE - | BLK_PERM_RESIZE, + perms, BLK_PERM_CONSISTENT_READ | BLK_PERM_GRAPH_MOD | BLK_PERM_WRITE_UNCHANGED); @@ -412,19 +457,22 @@ int bdrv_commit(BlockDriverState *bs) if (!drv) return -ENOMEDIUM; - if (!bs->backing) { + backing_file_bs = bdrv_filtered_cow_bs(bs); + + if (!backing_file_bs) { return -ENOTSUP; } if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT_SOURCE, NULL) || - bdrv_op_is_blocked(bs->backing->bs, BLOCK_OP_TYPE_COMMIT_TARGET, NULL)) { + bdrv_op_is_blocked(backing_file_bs, BLOCK_OP_TYPE_COMMIT_TARGET, NULL)) + { return -EBUSY; } - ro = bs->backing->bs->read_only; + ro = backing_file_bs->read_only; if (ro) { - if (bdrv_reopen_set_read_only(bs->backing->bs, false, NULL)) { + if (bdrv_reopen_set_read_only(backing_file_bs, false, NULL)) { return -EACCES; } } @@ -440,8 +488,6 @@ int bdrv_commit(BlockDriverState *bs) } /* Insert commit_top block node above backing, so we can write to it */ - backing_file_bs = backing_bs(bs); - commit_top_bs = bdrv_new_open_driver(&bdrv_commit_top, NULL, BDRV_O_RDWR, &local_err); if (commit_top_bs == NULL) { @@ -526,15 +572,13 @@ ro_cleanup: qemu_vfree(buf); blk_unref(backing); - if (backing_file_bs) { - bdrv_set_backing_hd(bs, backing_file_bs, &error_abort); - } + bdrv_set_backing_hd(bs, backing_file_bs, &error_abort); bdrv_unref(commit_top_bs); blk_unref(src); if (ro) { /* ignoring error return here */ - bdrv_reopen_set_read_only(bs->backing->bs, true, NULL); + bdrv_reopen_set_read_only(backing_file_bs, true, NULL); } return ret; diff --git a/blockdev.c b/blockdev.c index c6f79b4e0e..7bef41c0b0 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1094,7 +1094,7 @@ void hmp_commit(Monitor *mon, const QDict *qdict) return; } - bs = blk_bs(blk); + bs = bdrv_skip_implicit_filters(blk_bs(blk)); aio_context = bdrv_get_aio_context(bs); aio_context_acquire(aio_context); @@ -3454,7 +3454,9 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device, assert(bdrv_get_aio_context(base_bs) == aio_context); - for (iter = top_bs; iter != backing_bs(base_bs); iter = backing_bs(iter)) { + for (iter = top_bs; iter != bdrv_filtered_bs(base_bs); + iter = bdrv_filtered_bs(iter)) + { if (bdrv_op_is_blocked(iter, BLOCK_OP_TYPE_COMMIT_TARGET, errp)) { goto out; } From patchwork Fri Aug 9 16:13:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087239 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 D191013AC for ; Fri, 9 Aug 2019 16:25:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C04BB2015F for ; Fri, 9 Aug 2019 16:25:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B528820243; Fri, 9 Aug 2019 16:25: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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2BAB62015F for ; Fri, 9 Aug 2019 16:25:16 +0000 (UTC) Received: from localhost ([::1]:60998 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7hb-00008E-HC for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:25:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57523) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Y3-0003ST-7c for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Y1-0004Xt-LE for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:23 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36373) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Xy-0004Ue-8c; Fri, 09 Aug 2019 12:15:18 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 91805796ED; Fri, 9 Aug 2019 16:15:17 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E6F445DC1E; Fri, 9 Aug 2019 16:15:16 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:53 +0200 Message-Id: <20190809161407.11920-29-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Fri, 09 Aug 2019 16:15:17 +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 v6 28/42] stream: Deal with filters X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Because of the recent changes that make the stream job independent of the base node and instead track the node above it, we have to split that "bottom" node into two cases: The bottom COW node, and the node directly above the base node (which may be an R/W filter or the bottom COW node). Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- qapi/block-core.json | 4 ++++ block/stream.c | 52 ++++++++++++++++++++++++++++---------------- blockdev.c | 2 +- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 38c4dbd7c3..3c54717870 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2516,6 +2516,10 @@ # On successful completion the image file is updated to drop the backing file # and the BLOCK_JOB_COMPLETED event is emitted. # +# In case @device is a filter node, block-stream modifies the first non-filter +# overlay node below it to point to base's backing node (or NULL if @base was +# not specified) instead of modifying @device itself. +# # @job-id: identifier for the newly-created block job. If # omitted, the device name will be used. (Since 2.7) # diff --git a/block/stream.c b/block/stream.c index 4c8b89884a..bd4a351dae 100644 --- a/block/stream.c +++ b/block/stream.c @@ -31,7 +31,8 @@ enum { typedef struct StreamBlockJob { BlockJob common; - BlockDriverState *bottom; + BlockDriverState *bottom_cow_node; + BlockDriverState *above_base; BlockdevOnError on_error; char *backing_file_str; bool bs_read_only; @@ -54,7 +55,7 @@ static void stream_abort(Job *job) if (s->chain_frozen) { BlockJob *bjob = &s->common; - bdrv_unfreeze_chain(blk_bs(bjob->blk), s->bottom); + bdrv_unfreeze_chain(blk_bs(bjob->blk), s->above_base); } } @@ -63,14 +64,15 @@ static int stream_prepare(Job *job) StreamBlockJob *s = container_of(job, StreamBlockJob, common.job); BlockJob *bjob = &s->common; BlockDriverState *bs = blk_bs(bjob->blk); - BlockDriverState *base = backing_bs(s->bottom); + BlockDriverState *unfiltered_bs = bdrv_skip_rw_filters(bs); + BlockDriverState *base = bdrv_filtered_bs(s->above_base); Error *local_err = NULL; int ret = 0; - bdrv_unfreeze_chain(bs, s->bottom); + bdrv_unfreeze_chain(bs, s->above_base); s->chain_frozen = false; - if (bs->backing) { + if (bdrv_filtered_cow_child(unfiltered_bs)) { const char *base_id = NULL, *base_fmt = NULL; if (base) { base_id = s->backing_file_str; @@ -78,8 +80,8 @@ static int stream_prepare(Job *job) base_fmt = base->drv->format_name; } } - bdrv_set_backing_hd(bs, base, &local_err); - ret = bdrv_change_backing_file(bs, base_id, base_fmt); + bdrv_set_backing_hd(unfiltered_bs, base, &local_err); + ret = bdrv_change_backing_file(unfiltered_bs, base_id, base_fmt); if (local_err) { error_report_err(local_err); return -EPERM; @@ -110,7 +112,8 @@ static int coroutine_fn stream_run(Job *job, Error **errp) StreamBlockJob *s = container_of(job, StreamBlockJob, common.job); BlockBackend *blk = s->common.blk; BlockDriverState *bs = blk_bs(blk); - bool enable_cor = !backing_bs(s->bottom); + BlockDriverState *unfiltered_bs = bdrv_skip_rw_filters(bs); + bool enable_cor = !bdrv_filtered_bs(s->above_base); int64_t len; int64_t offset = 0; uint64_t delay_ns = 0; @@ -119,7 +122,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp) int64_t n = 0; /* bytes */ void *buf; - if (bs == s->bottom) { + if (unfiltered_bs == s->bottom_cow_node) { /* Nothing to stream */ return 0; } @@ -154,13 +157,14 @@ static int coroutine_fn stream_run(Job *job, Error **errp) copy = false; - ret = bdrv_is_allocated(bs, offset, STREAM_BUFFER_SIZE, &n); + ret = bdrv_is_allocated(unfiltered_bs, offset, STREAM_BUFFER_SIZE, &n); if (ret == 1) { /* Allocated in the top, no need to copy. */ } else if (ret >= 0) { /* Copy if allocated in the intermediate images. Limit to the * known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE). */ - ret = bdrv_is_allocated_above(backing_bs(bs), s->bottom, true, + ret = bdrv_is_allocated_above(bdrv_filtered_cow_bs(unfiltered_bs), + s->bottom_cow_node, true, offset, n, &n); /* Finish early if end of backing file has been reached */ if (ret == 0 && n == 0) { @@ -231,9 +235,16 @@ void stream_start(const char *job_id, BlockDriverState *bs, BlockDriverState *iter; bool bs_read_only; int basic_flags = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED; - BlockDriverState *bottom = bdrv_find_overlay(bs, base); + BlockDriverState *bottom_cow_node = bdrv_find_overlay(bs, base); + BlockDriverState *above_base; - if (bdrv_freeze_chain(bs, bottom, errp) < 0) { + /* Find the node directly above @base */ + for (above_base = bottom_cow_node; + bdrv_filtered_bs(above_base) != base; + above_base = bdrv_filtered_bs(above_base)) + {} + + if (bdrv_freeze_chain(bs, above_base, errp) < 0) { return; } @@ -261,16 +272,19 @@ void stream_start(const char *job_id, BlockDriverState *bs, * disappear from the chain after this operation. The streaming job reads * every block only once, assuming that it doesn't change, so forbid writes * and resizes. Reassign the base node pointer because the backing BS of the - * bottom node might change after the call to bdrv_reopen_set_read_only() - * due to parallel block jobs running. + * above_base node might change after the call to + * bdrv_reopen_set_read_only() due to parallel block jobs running. */ - base = backing_bs(bottom); - for (iter = backing_bs(bs); iter && iter != base; iter = backing_bs(iter)) { + base = bdrv_filtered_bs(above_base); + for (iter = bdrv_filtered_bs(bs); iter && iter != base; + iter = bdrv_filtered_bs(iter)) + { block_job_add_bdrv(&s->common, "intermediate node", iter, 0, basic_flags, &error_abort); } - s->bottom = bottom; + s->bottom_cow_node = bottom_cow_node; + s->above_base = above_base; s->backing_file_str = g_strdup(backing_file_str); s->bs_read_only = bs_read_only; s->chain_frozen = true; @@ -284,5 +298,5 @@ fail: if (bs_read_only) { bdrv_reopen_set_read_only(bs, true, NULL); } - bdrv_unfreeze_chain(bs, bottom); + bdrv_unfreeze_chain(bs, above_base); } diff --git a/blockdev.c b/blockdev.c index 7bef41c0b0..ee8b951154 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3297,7 +3297,7 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device, } /* Check for op blockers in the whole chain between bs and base */ - for (iter = bs; iter && iter != base_bs; iter = backing_bs(iter)) { + for (iter = bs; iter && iter != base_bs; iter = bdrv_filtered_bs(iter)) { if (bdrv_op_is_blocked(iter, BLOCK_OP_TYPE_STREAM, errp)) { goto out; } From patchwork Fri Aug 9 16:13:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087273 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 880C114D5 for ; Fri, 9 Aug 2019 16:29:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7782520069 for ; Fri, 9 Aug 2019 16:29:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6B8E120408; Fri, 9 Aug 2019 16:29:58 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1F4C6203B9 for ; Fri, 9 Aug 2019 16:29:57 +0000 (UTC) Received: from localhost ([::1]:32860 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7m9-0003Mz-Ac for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:29:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57533) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Y3-0003UB-Nq for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Y2-0004ZJ-Nf for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:23 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51524) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Y0-0004Vm-G3; Fri, 09 Aug 2019 12:15:20 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D090B3172D8D; Fri, 9 Aug 2019 16:15:19 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 678183796; Fri, 9 Aug 2019 16:15:19 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:54 +0200 Message-Id: <20190809161407.11920-30-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Fri, 09 Aug 2019 16:15:19 +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 v6 29/42] nbd: Use CAF when looking for dirty bitmap X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP When looking for a dirty bitmap to share, we should handle filters by just including them in the search (so they do not break backing chains). Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Eric Blake --- nbd/server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index fbd51b48a7..a1c73ce957 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1511,13 +1511,13 @@ NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset, if (bitmap) { BdrvDirtyBitmap *bm = NULL; - while (true) { + while (bs) { bm = bdrv_find_dirty_bitmap(bs, bitmap); - if (bm != NULL || bs->backing == NULL) { + if (bm != NULL) { break; } - bs = bs->backing->bs; + bs = bdrv_filtered_bs(bs); } if (bm == NULL) { From patchwork Fri Aug 9 16:13:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087265 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 BF12E14D5 for ; Fri, 9 Aug 2019 16:27:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ABB0C2015F for ; Fri, 9 Aug 2019 16:27:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9E1D72022B; Fri, 9 Aug 2019 16:27:58 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2FB9720243 for ; Fri, 9 Aug 2019 16:27:58 +0000 (UTC) Received: from localhost ([::1]:32822 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7kD-00078y-HS for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:27:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57585) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Y7-0003ho-01 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Y5-0004b5-OE for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:54880) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Y2-0004Z1-TX; Fri, 09 Aug 2019 12:15:23 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 341D330ADBA6; Fri, 9 Aug 2019 16:15:22 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A9FDE17C4A; Fri, 9 Aug 2019 16:15:21 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:55 +0200 Message-Id: <20190809161407.11920-31-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Fri, 09 Aug 2019 16:15:22 +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 v6 30/42] qemu-img: Use child access functions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This changes iotest 204's output, because blkdebug on top of a COW node used to make qemu-img map disregard the rest of the backing chain (the backing chain was broken by the filter). With this patch, the allocation in the base image is reported correctly. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- qemu-img.c | 33 ++++++++++++++++++++------------- tests/qemu-iotests/204.out | 1 + 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index 79983772de..3b30c5ae70 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1012,7 +1012,7 @@ static int img_commit(int argc, char **argv) /* This is different from QMP, which by default uses the deepest file in * the backing chain (i.e., the very base); however, the traditional * behavior of qemu-img commit is using the immediate backing file. */ - base_bs = backing_bs(bs); + base_bs = bdrv_backing_chain_next(bs); if (!base_bs) { error_setg(&local_err, "Image does not have a backing file"); goto done; @@ -1632,18 +1632,20 @@ static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num) if (s->sector_next_status <= sector_num) { uint64_t offset = (sector_num - src_cur_offset) * BDRV_SECTOR_SIZE; int64_t count; + BlockDriverState *src_bs = blk_bs(s->src[src_cur]); + BlockDriverState *base; + + if (s->target_has_backing) { + base = bdrv_filtered_cow_bs(bdrv_skip_rw_filters(src_bs)); + } else { + base = NULL; + } do { count = n * BDRV_SECTOR_SIZE; - if (s->target_has_backing) { - ret = bdrv_block_status(blk_bs(s->src[src_cur]), offset, - count, &count, NULL, NULL); - } else { - ret = bdrv_block_status_above(blk_bs(s->src[src_cur]), NULL, - offset, count, &count, NULL, - NULL); - } + ret = bdrv_block_status_above(src_bs, base, offset, count, &count, + NULL, NULL); if (ret < 0) { if (s->salvage) { @@ -2490,7 +2492,8 @@ static int img_convert(int argc, char **argv) * s.target_backing_sectors has to be negative, which it will * be automatically). The backing file length is used only * for optimizations, so such a case is not fatal. */ - s.target_backing_sectors = bdrv_nb_sectors(out_bs->backing->bs); + s.target_backing_sectors = + bdrv_nb_sectors(bdrv_filtered_cow_bs(out_bs)); } else { s.target_backing_sectors = -1; } @@ -2853,6 +2856,7 @@ static int get_block_status(BlockDriverState *bs, int64_t offset, depth = 0; for (;;) { + bs = bdrv_skip_rw_filters(bs); ret = bdrv_block_status(bs, offset, bytes, &bytes, &map, &file); if (ret < 0) { return ret; @@ -2861,7 +2865,7 @@ static int get_block_status(BlockDriverState *bs, int64_t offset, if (ret & (BDRV_BLOCK_ZERO|BDRV_BLOCK_DATA)) { break; } - bs = backing_bs(bs); + bs = bdrv_filtered_cow_bs(bs); if (bs == NULL) { ret = 0; break; @@ -3216,6 +3220,7 @@ static int img_rebase(int argc, char **argv) uint8_t *buf_old = NULL; uint8_t *buf_new = NULL; BlockDriverState *bs = NULL, *prefix_chain_bs = NULL; + BlockDriverState *unfiltered_bs; char *filename; const char *fmt, *cache, *src_cache, *out_basefmt, *out_baseimg; int c, flags, src_flags, ret; @@ -3350,6 +3355,8 @@ static int img_rebase(int argc, char **argv) } bs = blk_bs(blk); + unfiltered_bs = bdrv_skip_rw_filters(bs); + if (out_basefmt != NULL) { if (bdrv_find_format(out_basefmt) == NULL) { error_report("Invalid format name: '%s'", out_basefmt); @@ -3361,7 +3368,7 @@ static int img_rebase(int argc, char **argv) /* For safe rebasing we need to compare old and new backing file */ if (!unsafe) { QDict *options = NULL; - BlockDriverState *base_bs = backing_bs(bs); + BlockDriverState *base_bs = bdrv_filtered_cow_bs(unfiltered_bs); if (base_bs) { blk_old_backing = blk_new(qemu_get_aio_context(), @@ -3517,7 +3524,7 @@ static int img_rebase(int argc, char **argv) * If cluster wasn't changed since prefix_chain, we don't need * to take action */ - ret = bdrv_is_allocated_above(backing_bs(bs), prefix_chain_bs, + ret = bdrv_is_allocated_above(unfiltered_bs, prefix_chain_bs, false, offset, n, &n); if (ret < 0) { error_report("error while reading image metadata: %s", diff --git a/tests/qemu-iotests/204.out b/tests/qemu-iotests/204.out index f3a10fbe90..684774d763 100644 --- a/tests/qemu-iotests/204.out +++ b/tests/qemu-iotests/204.out @@ -59,5 +59,6 @@ Offset Length File 0x900000 0x2400000 TEST_DIR/t.IMGFMT 0x3c00000 0x1100000 TEST_DIR/t.IMGFMT 0x6a00000 0x400000 TEST_DIR/t.IMGFMT +0x6e00000 0x1200000 TEST_DIR/t.IMGFMT.base No errors were found on the image. *** done From patchwork Fri Aug 9 16:13:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087219 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 0965613AC for ; Fri, 9 Aug 2019 16:23:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E8A95201A4 for ; Fri, 9 Aug 2019 16:23:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D531A2015F; Fri, 9 Aug 2019 16:23:15 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 861B22015F for ; Fri, 9 Aug 2019 16:23:15 +0000 (UTC) Received: from localhost ([::1]:60968 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7fe-00058s-Tv for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:23:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57599) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Y8-0003lC-35 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Y7-0004bq-62 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:60493) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Y5-0004af-3O; Fri, 09 Aug 2019 12:15:25 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6E27F3081CFE; Fri, 9 Aug 2019 16:15:24 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 092637E4E; Fri, 9 Aug 2019 16:15:23 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:56 +0200 Message-Id: <20190809161407.11920-32-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Fri, 09 Aug 2019 16:15:24 +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 v6 31/42] block: Drop backing_bs() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP We want to make it explicit where bs->backing is used, and we have done so. The old role of backing_bs() is now effectively taken by bdrv_filtered_cow_bs(). Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/block_int.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/block/block_int.h b/include/block/block_int.h index 5bec3361fd..786801c32f 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -932,11 +932,6 @@ typedef enum BlockMirrorBackingMode { MIRROR_LEAVE_BACKING_CHAIN, } BlockMirrorBackingMode; -static inline BlockDriverState *backing_bs(BlockDriverState *bs) -{ - return bs->backing ? bs->backing->bs : NULL; -} - /* Essential block drivers which must always be statically linked into qemu, and * which therefore can be accessed without using bdrv_find_format() */ From patchwork Fri Aug 9 16:13:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087271 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 65D5413AC for ; Fri, 9 Aug 2019 16:28:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 543881FFCA for ; Fri, 9 Aug 2019 16:28:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 485AC202A5; Fri, 9 Aug 2019 16:28: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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EC7D6200CB for ; Fri, 9 Aug 2019 16:28:51 +0000 (UTC) Received: from localhost ([::1]:32844 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7l5-0001jJ-Bb for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:28:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57627) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7YB-0003up-20 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Y9-0004dD-P7 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:30 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45734) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Y7-0004bc-DP; Fri, 09 Aug 2019 12:15:27 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AA08665F7B; Fri, 9 Aug 2019 16:15:26 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 472CA5C8BA; Fri, 9 Aug 2019 16:15:26 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:57 +0200 Message-Id: <20190809161407.11920-33-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Fri, 09 Aug 2019 16:15:26 +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 v6 32/42] block: Make bdrv_get_cumulative_perm() public X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This is useful in other files like blockdev.c to determine for example whether a node can be written to or not. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/block_int.h | 3 +++ block.c | 6 ++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/block/block_int.h b/include/block/block_int.h index 786801c32f..c17df3808a 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -1205,6 +1205,9 @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared, */ int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp); +void bdrv_get_cumulative_perm(BlockDriverState *bs, + uint64_t *perm, uint64_t *shared_perm); + /* Default implementation for BlockDriver.bdrv_child_perm() that can be used by * block filters: Forward CONSISTENT_READ, WRITE, WRITE_UNCHANGED and RESIZE to * all children */ diff --git a/block.c b/block.c index 6e1ddab056..915b80153c 100644 --- a/block.c +++ b/block.c @@ -1713,8 +1713,6 @@ static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q, bool *tighten_restrictions, Error **errp); static void bdrv_child_abort_perm_update(BdrvChild *c); static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared); -static void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm, - uint64_t *shared_perm); typedef struct BlockReopenQueueEntry { bool prepared; @@ -1938,8 +1936,8 @@ static void bdrv_set_perm(BlockDriverState *bs, uint64_t cumulative_perms, } } -static void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm, - uint64_t *shared_perm) +void bdrv_get_cumulative_perm(BlockDriverState *bs, + uint64_t *perm, uint64_t *shared_perm) { BdrvChild *c; uint64_t cumulative_perms = 0; From patchwork Fri Aug 9 16:13:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087275 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 9E4B213AC for ; Fri, 9 Aug 2019 16:30:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8A695202A5 for ; Fri, 9 Aug 2019 16:30:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7F118202DB; Fri, 9 Aug 2019 16:30:00 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2D193202A5 for ; Fri, 9 Aug 2019 16:30:00 +0000 (UTC) Received: from localhost ([::1]:32862 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7mB-0003SE-Do for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:29:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57656) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7YE-0003yh-IG for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7YC-0004eZ-LA for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:34 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51518) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7Y9-0004cd-LU; Fri, 09 Aug 2019 12:15:29 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EA5367EBC4; Fri, 9 Aug 2019 16:15:28 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 858895D9D3; Fri, 9 Aug 2019 16:15:28 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:58 +0200 Message-Id: <20190809161407.11920-34-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Fri, 09 Aug 2019 16:15:28 +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 v6 33/42] blockdev: Fix active commit choice X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP We have to perform an active commit whenever the top node has a parent that has taken the WRITE permission on it. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- blockdev.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/blockdev.c b/blockdev.c index ee8b951154..4e72f6f701 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3356,6 +3356,7 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device, */ BlockdevOnError on_error = BLOCKDEV_ON_ERROR_REPORT; int job_flags = JOB_DEFAULT; + uint64_t top_perm, top_shared; if (!has_speed) { speed = 0; @@ -3468,14 +3469,31 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device, goto out; } - if (top_bs == bs) { + /* + * Active commit is required if and only if someone has taken a + * WRITE permission on the top node. Historically, we have always + * used active commit for top nodes, so continue that practice. + * (Active commit is never really wrong.) + */ + bdrv_get_cumulative_perm(top_bs, &top_perm, &top_shared); + if (top_perm & BLK_PERM_WRITE || + bdrv_skip_rw_filters(top_bs) == bdrv_skip_rw_filters(bs)) + { if (has_backing_file) { error_setg(errp, "'backing-file' specified," " but 'top' is the active layer"); goto out; } - commit_active_start(has_job_id ? job_id : NULL, bs, base_bs, - job_flags, speed, on_error, + if (!has_job_id) { + /* + * Emulate here what block_job_create() does, because it + * is possible that @bs != @top_bs (the block job should + * be named after @bs, even if @top_bs is the actual + * source) + */ + job_id = bdrv_get_device_name(bs); + } + commit_active_start(job_id, top_bs, base_bs, job_flags, speed, on_error, filter_node_name, NULL, NULL, false, &local_err); } else { BlockDriverState *overlay_bs = bdrv_find_overlay(bs, top_bs); From patchwork Fri Aug 9 16:13:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087249 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 4747913AC for ; Fri, 9 Aug 2019 16:27:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3481A201F3 for ; Fri, 9 Aug 2019 16:27:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2907B202DB; Fri, 9 Aug 2019 16:27:06 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7F355201F3 for ; Fri, 9 Aug 2019 16:27:05 +0000 (UTC) Received: from localhost ([::1]:32802 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7jM-0004Tw-QZ for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:27:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57705) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7YN-0003zm-UG for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7YM-0004ho-0o for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:54140) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7YC-0004e3-2j; Fri, 09 Aug 2019 12:15:32 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6694C99BAC; Fri, 9 Aug 2019 16:15:31 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C64D65D6A9; Fri, 9 Aug 2019 16:15:30 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:13:59 +0200 Message-Id: <20190809161407.11920-35-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 09 Aug 2019 16:15:31 +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 v6 34/42] block: Inline bdrv_co_block_status_from_*() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP With bdrv_filtered_rw_bs(), we can easily handle this default filter behavior in bdrv_co_block_status(). blkdebug wants to have an additional assertion, so it keeps its own implementation, except bdrv_co_block_status_from_file() needs to be inlined there. Suggested-by: Eric Blake Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/block_int.h | 22 ----------------- block/blkdebug.c | 7 ++++-- block/blklogwrites.c | 1 - block/commit.c | 1 - block/copy-on-read.c | 2 -- block/io.c | 51 +++++++++++++-------------------------- block/mirror.c | 1 - block/throttle.c | 1 - 8 files changed, 22 insertions(+), 64 deletions(-) diff --git a/include/block/block_int.h b/include/block/block_int.h index c17df3808a..42ee2fcf7f 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -1227,28 +1227,6 @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared); -/* - * Default implementation for drivers to pass bdrv_co_block_status() to - * their file. - */ -int coroutine_fn bdrv_co_block_status_from_file(BlockDriverState *bs, - bool want_zero, - int64_t offset, - int64_t bytes, - int64_t *pnum, - int64_t *map, - BlockDriverState **file); -/* - * Default implementation for drivers to pass bdrv_co_block_status() to - * their backing file. - */ -int coroutine_fn bdrv_co_block_status_from_backing(BlockDriverState *bs, - bool want_zero, - int64_t offset, - int64_t bytes, - int64_t *pnum, - int64_t *map, - BlockDriverState **file); const char *bdrv_get_parent_name(const BlockDriverState *bs); void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp); bool blk_dev_has_removable_media(BlockBackend *blk); diff --git a/block/blkdebug.c b/block/blkdebug.c index 5ae96c52b0..0011e068ce 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -679,8 +679,11 @@ static int coroutine_fn blkdebug_co_block_status(BlockDriverState *bs, return err; } - return bdrv_co_block_status_from_file(bs, want_zero, offset, bytes, - pnum, map, file); + assert(bs->file && bs->file->bs); + *pnum = bytes; + *map = offset; + *file = bs->file->bs; + return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID; } static void blkdebug_close(BlockDriverState *bs) diff --git a/block/blklogwrites.c b/block/blklogwrites.c index 04d8b33607..8982fd15c4 100644 --- a/block/blklogwrites.c +++ b/block/blklogwrites.c @@ -519,7 +519,6 @@ static BlockDriver bdrv_blk_log_writes = { .bdrv_co_pwrite_zeroes = blk_log_writes_co_pwrite_zeroes, .bdrv_co_flush_to_disk = blk_log_writes_co_flush_to_disk, .bdrv_co_pdiscard = blk_log_writes_co_pdiscard, - .bdrv_co_block_status = bdrv_co_block_status_from_file, .is_filter = true, .strong_runtime_opts = blk_log_writes_strong_runtime_opts, diff --git a/block/commit.c b/block/commit.c index 40d1c8eeac..c94678bea3 100644 --- a/block/commit.c +++ b/block/commit.c @@ -252,7 +252,6 @@ static void bdrv_commit_top_child_perm(BlockDriverState *bs, BdrvChild *c, static BlockDriver bdrv_commit_top = { .format_name = "commit_top", .bdrv_co_preadv = bdrv_commit_top_preadv, - .bdrv_co_block_status = bdrv_co_block_status_from_backing, .bdrv_refresh_filename = bdrv_commit_top_refresh_filename, .bdrv_child_perm = bdrv_commit_top_child_perm, diff --git a/block/copy-on-read.c b/block/copy-on-read.c index 16bdf630b6..ad6577d078 100644 --- a/block/copy-on-read.c +++ b/block/copy-on-read.c @@ -160,8 +160,6 @@ static BlockDriver bdrv_copy_on_read = { .bdrv_eject = cor_eject, .bdrv_lock_medium = cor_lock_medium, - .bdrv_co_block_status = bdrv_co_block_status_from_file, - .bdrv_recurse_is_first_non_filter = cor_recurse_is_first_non_filter, .has_variable_length = true, diff --git a/block/io.c b/block/io.c index e222d91893..d7d9757f46 100644 --- a/block/io.c +++ b/block/io.c @@ -2028,36 +2028,6 @@ typedef struct BdrvCoBlockStatusData { bool done; } BdrvCoBlockStatusData; -int coroutine_fn bdrv_co_block_status_from_file(BlockDriverState *bs, - bool want_zero, - int64_t offset, - int64_t bytes, - int64_t *pnum, - int64_t *map, - BlockDriverState **file) -{ - assert(bs->file && bs->file->bs); - *pnum = bytes; - *map = offset; - *file = bs->file->bs; - return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID; -} - -int coroutine_fn bdrv_co_block_status_from_backing(BlockDriverState *bs, - bool want_zero, - int64_t offset, - int64_t bytes, - int64_t *pnum, - int64_t *map, - BlockDriverState **file) -{ - assert(bs->backing && bs->backing->bs); - *pnum = bytes; - *map = offset; - *file = bs->backing->bs; - return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID; -} - /* * Returns the allocation status of the specified sectors. * Drivers not implementing the functionality are assumed to not support @@ -2098,6 +2068,7 @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs, BlockDriverState *local_file = NULL; int64_t aligned_offset, aligned_bytes; uint32_t align; + bool has_filtered_child; assert(pnum); *pnum = 0; @@ -2123,7 +2094,8 @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs, /* Must be non-NULL or bdrv_getlength() would have failed */ assert(bs->drv); - if (!bs->drv->bdrv_co_block_status) { + has_filtered_child = bs->drv->is_filter && bdrv_filtered_rw_child(bs); + if (!bs->drv->bdrv_co_block_status && !has_filtered_child) { *pnum = bytes; ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED; if (offset + bytes == total_size) { @@ -2144,9 +2116,20 @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs, aligned_offset = QEMU_ALIGN_DOWN(offset, align); aligned_bytes = ROUND_UP(offset + bytes, align) - aligned_offset; - ret = bs->drv->bdrv_co_block_status(bs, want_zero, aligned_offset, - aligned_bytes, pnum, &local_map, - &local_file); + if (bs->drv->bdrv_co_block_status) { + ret = bs->drv->bdrv_co_block_status(bs, want_zero, aligned_offset, + aligned_bytes, pnum, &local_map, + &local_file); + } else { + /* Default code for filters */ + + local_file = bdrv_filtered_rw_bs(bs); + assert(local_file); + + *pnum = aligned_bytes; + local_map = aligned_offset; + ret = BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID; + } if (ret < 0) { *pnum = 0; goto out; diff --git a/block/mirror.c b/block/mirror.c index 6ddbfb9708..88155faaec 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -1508,7 +1508,6 @@ static BlockDriver bdrv_mirror_top = { .bdrv_co_pwrite_zeroes = bdrv_mirror_top_pwrite_zeroes, .bdrv_co_pdiscard = bdrv_mirror_top_pdiscard, .bdrv_co_flush = bdrv_mirror_top_flush, - .bdrv_co_block_status = bdrv_co_block_status_from_backing, .bdrv_refresh_filename = bdrv_mirror_top_refresh_filename, .bdrv_child_perm = bdrv_mirror_top_child_perm, .bdrv_refresh_limits = bdrv_mirror_top_refresh_limits, diff --git a/block/throttle.c b/block/throttle.c index 958a2bcfa6..d0436f875b 100644 --- a/block/throttle.c +++ b/block/throttle.c @@ -270,7 +270,6 @@ static BlockDriver bdrv_throttle = { .bdrv_reopen_prepare = throttle_reopen_prepare, .bdrv_reopen_commit = throttle_reopen_commit, .bdrv_reopen_abort = throttle_reopen_abort, - .bdrv_co_block_status = bdrv_co_block_status_from_file, .bdrv_co_drain_begin = throttle_co_drain_begin, .bdrv_co_drain_end = throttle_co_drain_end, From patchwork Fri Aug 9 16:14:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087287 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 BF370746 for ; Fri, 9 Aug 2019 16:32:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC4A61FE82 for ; Fri, 9 Aug 2019 16:32:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A03F020134; Fri, 9 Aug 2019 16:32:43 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1551F1FE82 for ; Fri, 9 Aug 2019 16:32:43 +0000 (UTC) Received: from localhost ([::1]:32917 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7oo-0008KJ-GI for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:32:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57751) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7YR-00044O-RN for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7YP-0004jH-PR for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:47 -0400 Received: from mx1.redhat.com ([209.132.183.28]:37280) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7YE-0004f6-Hn; Fri, 09 Aug 2019 12:15:35 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D4DBE20ABB; Fri, 9 Aug 2019 16:15:33 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 404345D6A0; Fri, 9 Aug 2019 16:15:33 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:14:00 +0200 Message-Id: <20190809161407.11920-36-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 09 Aug 2019 16:15:33 +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 v6 35/42] block: Fix check_to_replace_node() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Currently, check_to_replace_node() only allows mirror to replace a node in the chain of the source node, and only if it is the first non-filter node below the source. Well, technically, the idea is that you can exactly replace a quorum child by mirroring from quorum. This has (probably) two reasons: (1) We do not want to create loops. (2) @replaces and @device should have exactly the same content so replacing them does not cause visible data to change. This has two issues: (1) It is overly restrictive. It is completely fine for @replaces to be a filter. (2) It is not restrictive enough. You can create loops with this as follows: $ qemu-img create -f qcow2 /tmp/source.qcow2 64M $ qemu-system-x86_64 -qmp stdio {"execute": "qmp_capabilities"} {"execute": "object-add", "arguments": {"qom-type": "throttle-group", "id": "tg0"}} {"execute": "blockdev-add", "arguments": { "node-name": "source", "driver": "throttle", "throttle-group": "tg0", "file": { "node-name": "filtered", "driver": "qcow2", "file": { "driver": "file", "filename": "/tmp/source.qcow2" } } } } {"execute": "drive-mirror", "arguments": { "job-id": "mirror", "device": "source", "target": "/tmp/target.qcow2", "format": "qcow2", "node-name": "target", "sync" :"none", "replaces": "filtered" } } {"execute": "block-job-complete", "arguments": {"device": "mirror"}} And qemu crashes because of a stack overflow due to the loop being created (target's backing file is source, so when it replaces filtered, it points to itself through source). (blockdev-mirror can be broken similarly.) So let us make the checks for the two conditions above explicit, which makes the whole function exactly as restrictive as it needs to be. Signed-off-by: Max Reitz --- include/block/block.h | 1 + block.c | 83 +++++++++++++++++++++++++++++++++++++++---- blockdev.c | 34 ++++++++++++++++-- 3 files changed, 110 insertions(+), 8 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index 6ba853fb90..8da706cd89 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -404,6 +404,7 @@ bool bdrv_is_first_non_filter(BlockDriverState *candidate); /* check if a named node can be replaced when doing drive-mirror */ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, + BlockDriverState *backing_bs, const char *node_name, Error **errp); /* async block I/O */ diff --git a/block.c b/block.c index 915b80153c..4858d3e718 100644 --- a/block.c +++ b/block.c @@ -6290,7 +6290,59 @@ bool bdrv_is_first_non_filter(BlockDriverState *candidate) return false; } +static bool is_child_of(BlockDriverState *child, BlockDriverState *parent) +{ + BdrvChild *c; + + if (!parent) { + return false; + } + + QLIST_FOREACH(c, &parent->children, next) { + if (c->bs == child || is_child_of(child, c->bs)) { + return true; + } + } + + return false; +} + +/* + * Return true if there are only filters in [@top, @base). Note that + * this may include quorum (which bdrv_chain_contains() cannot + * handle). + */ +static bool is_filtered_child(BlockDriverState *top, BlockDriverState *base) +{ + BdrvChild *c; + + if (!top) { + return false; + } + + if (top == base) { + return true; + } + + if (!top->drv->is_filter) { + return false; + } + + QLIST_FOREACH(c, &top->children, next) { + if (is_filtered_child(c->bs, base)) { + return true; + } + } + + return false; +} + +/* + * @parent_bs is mirror's source BDS, @backing_bs is the BDS which + * will be attached to the target when mirror completes. + */ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, + BlockDriverState *backing_bs, const char *node_name, Error **errp) { BlockDriverState *to_replace_bs = bdrv_find_node(node_name); @@ -6309,13 +6361,32 @@ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, goto out; } - /* We don't want arbitrary node of the BDS chain to be replaced only the top - * most non filter in order to prevent data corruption. - * Another benefit is that this tests exclude backing files which are - * blocked by the backing blockers. + /* + * If to_replace_bs is (recursively) a child of backing_bs, + * replacing it may create a loop. We cannot allow that. */ - if (!bdrv_recurse_is_first_non_filter(parent_bs, to_replace_bs)) { - error_setg(errp, "Only top most non filter can be replaced"); + if (to_replace_bs == backing_bs || is_child_of(to_replace_bs, backing_bs)) { + error_setg(errp, "Replacing this node would result in a loop"); + to_replace_bs = NULL; + goto out; + } + + /* + * Mirror is designed in such a way that when it completes, the + * source BDS is seamlessly replaced. It is therefore not allowed + * to replace a BDS where this condition would be violated, as that + * would defeat the purpose of mirror and could lead to data + * corruption. + * Therefore, between parent_bs and to_replace_bs there may be + * only filters (and the one on top must be a filter, too), so + * their data always stays in sync and mirror can complete and + * replace to_replace_bs without any possible corruptions. + */ + if (!is_filtered_child(parent_bs, to_replace_bs) && + !is_filtered_child(to_replace_bs, parent_bs)) + { + error_setg(errp, "The node to be replaced must be connected to the " + "source through filter nodes only"); to_replace_bs = NULL; goto out; } diff --git a/blockdev.c b/blockdev.c index 4e72f6f701..758e0b5431 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3887,7 +3887,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, } if (has_replaces) { - BlockDriverState *to_replace_bs; + BlockDriverState *to_replace_bs, *backing_bs; AioContext *replace_aio_context; int64_t bs_size, replace_size; @@ -3897,7 +3897,37 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, return; } - to_replace_bs = check_to_replace_node(bs, replaces, errp); + if (backing_mode == MIRROR_SOURCE_BACKING_CHAIN || + backing_mode == MIRROR_OPEN_BACKING_CHAIN) + { + /* + * While we do not quite know what OPEN_BACKING_CHAIN + * (used for mode=existing) will yield, it is probably + * best to restrict it exactly like SOURCE_BACKING_CHAIN, + * because that is our best guess. + */ + switch (sync) { + case MIRROR_SYNC_MODE_FULL: + backing_bs = NULL; + break; + + case MIRROR_SYNC_MODE_TOP: + backing_bs = bdrv_filtered_cow_bs(bdrv_skip_rw_filters(bs)); + break; + + case MIRROR_SYNC_MODE_NONE: + backing_bs = bs; + break; + + default: + abort(); + } + } else { + assert(backing_mode == MIRROR_LEAVE_BACKING_CHAIN); + backing_bs = bdrv_filtered_cow_bs(bdrv_skip_rw_filters(target)); + } + + to_replace_bs = check_to_replace_node(bs, backing_bs, replaces, errp); if (!to_replace_bs) { return; } From patchwork Fri Aug 9 16:14:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087283 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 01911746 for ; Fri, 9 Aug 2019 16:31:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E297420069 for ; Fri, 9 Aug 2019 16:31:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D6C9E20134; Fri, 9 Aug 2019 16:31: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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6040F20069 for ; Fri, 9 Aug 2019 16:31:34 +0000 (UTC) Received: from localhost ([::1]:32894 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7nh-00064M-MF for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:31:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57750) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7YR-00044L-Qw for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7YP-0004jN-Q2 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:47 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50204) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7YG-0004fm-Q2; Fri, 09 Aug 2019 12:15:37 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1EDC230BD1DA; Fri, 9 Aug 2019 16:15:36 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id ABB935DC1E; Fri, 9 Aug 2019 16:15:35 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:14:01 +0200 Message-Id: <20190809161407.11920-37-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Fri, 09 Aug 2019 16:15:36 +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 v6 36/42] iotests: Add tests for mirror @replaces loops X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This adds two tests for cases where our old check_to_replace_node() function failed to detect that executing this job with these parameters would result in a cyclic graph. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- tests/qemu-iotests/041 | 124 +++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/041.out | 4 +- 2 files changed, 126 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index 26bf1701eb..0c1432f189 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -1067,5 +1067,129 @@ class TestOrphanedSource(iotests.QMPTestCase): target='dest-ro') self.assert_qmp(result, 'error/class', 'GenericError') +# Various tests for the @replaces option (independent of quorum) +class TestReplaces(iotests.QMPTestCase): + def setUp(self): + self.vm = iotests.VM() + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + + def test_drive_mirror_loop(self): + qemu_img('create', '-f', iotests.imgfmt, test_img, '1M') + + result = self.vm.qmp('object-add', qom_type='throttle-group', id='tg') + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('blockdev-add', **{ + 'node-name': 'source', + 'driver': 'throttle', + 'throttle-group': 'tg', + 'file': { + 'node-name': 'filtered', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': test_img + } + } + }) + self.assert_qmp(result, 'return', {}) + + # Mirror from @source to @target in sync=none, so that @source + # will be @target's backing file; but replace @filtered. + # Then, @target's backing file will be @source, whose backing + # file is now @target instead of @filtered. That is a loop. + # (But apart from the loop, replacing @filtered instead of + # @source is fine, because both are just filtered versions of + # each other.) + result = self.vm.qmp('drive-mirror', + job_id='mirror', + device='source', + target=target_img, + format=iotests.imgfmt, + node_name='target', + sync='none', + replaces='filtered') + if 'error' in result: + # This is the correct result + self.assert_qmp(result, 'error/class', 'GenericError') + else: + # This is wrong, but let's run it to the bitter conclusion + self.complete_and_wait(drive='mirror') + # Fail for good measure, although qemu should have crashed + # anyway + self.fail('Loop creation was successful') + + os.remove(test_img) + try: + os.remove(target_img) + except OSError: + pass + + def test_blockdev_mirror_loop(self): + qemu_img('create', '-f', iotests.imgfmt, test_img, '1M') + qemu_img('create', '-f', iotests.imgfmt, target_img, '1M') + + result = self.vm.qmp('object-add', qom_type='throttle-group', id='tg') + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('blockdev-add', **{ + 'node-name': 'source', + 'driver': 'throttle', + 'throttle-group': 'tg', + 'file': { + 'node-name': 'middle', + 'driver': 'throttle', + 'throttle-group': 'tg', + 'file': { + 'node-name': 'bottom', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': test_img + } + } + } + }) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('blockdev-add', **{ + 'node-name': 'target', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': target_img + }, + 'backing': 'middle' + }) + + # Mirror from @source to @target. With blockdev-mirror, the + # current (old) backing file is retained (which is @middle). + # By replacing @bottom, @middle's file will be @target, whose + # backing file is @middle again. That is a loop. + # (But apart from the loop, replacing @bottom instead of + # @source is fine, because both are just filtered versions of + # each other.) + result = self.vm.qmp('blockdev-mirror', + job_id='mirror', + device='source', + target='target', + sync='full', + replaces='bottom') + if 'error' in result: + # This is the correct result + self.assert_qmp(result, 'error/class', 'GenericError') + else: + # This is wrong, but let's run it to the bitter conclusion + self.complete_and_wait(drive='mirror') + # Fail for good measure, although qemu should have crashed + # anyway + self.fail('Loop creation was successful') + + os.remove(test_img) + os.remove(target_img) + if __name__ == '__main__': iotests.main(supported_fmts=['qcow2', 'qed']) diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out index e071d0b261..2c448b4239 100644 --- a/tests/qemu-iotests/041.out +++ b/tests/qemu-iotests/041.out @@ -1,5 +1,5 @@ -........................................................................................ +.......................................................................................... ---------------------------------------------------------------------- -Ran 88 tests +Ran 90 tests OK From patchwork Fri Aug 9 16:14:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087289 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 AF2EA14E5 for ; Fri, 9 Aug 2019 16:33:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9B8E31FE82 for ; Fri, 9 Aug 2019 16:33:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8F3E1200E7; Fri, 9 Aug 2019 16:33:49 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id AF5CD1FE82 for ; Fri, 9 Aug 2019 16:33:48 +0000 (UTC) Received: from localhost ([::1]:32928 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7ps-0001Me-18 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:33:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57793) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7YU-0004CV-7C for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7YS-0004kl-2J for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51740) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7YL-0004hR-WD; Fri, 09 Aug 2019 12:15:42 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D0B6E308A958; Fri, 9 Aug 2019 16:15:40 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id EADEE5D6A0; Fri, 9 Aug 2019 16:15:37 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:14:02 +0200 Message-Id: <20190809161407.11920-38-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Fri, 09 Aug 2019 16:15:40 +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 v6 37/42] block: Leave BDS.backing_file constant X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Parts of the block layer treat BDS.backing_file as if it were whatever the image header says (i.e., if it is a relative path, it is relative to the overlay), other parts treat it like a cache for bs->backing->bs->filename (relative paths are relative to the CWD). Considering bs->backing->bs->filename exists, let us make it mean the former. Among other things, this now allows the user to specify a base when using qemu-img to commit an image file in a directory that is not the CWD (assuming, everything uses relative filenames). Before this patch: $ ./qemu-img create -f qcow2 foo/bot.qcow2 1M $ ./qemu-img create -f qcow2 -b bot.qcow2 foo/mid.qcow2 $ ./qemu-img create -f qcow2 -b mid.qcow2 foo/top.qcow2 $ ./qemu-img commit -b mid.qcow2 foo/top.qcow2 qemu-img: Did not find 'mid.qcow2' in the backing chain of 'foo/top.qcow2' $ ./qemu-img commit -b foo/mid.qcow2 foo/top.qcow2 qemu-img: Did not find 'foo/mid.qcow2' in the backing chain of 'foo/top.qcow2' $ ./qemu-img commit -b $PWD/foo/mid.qcow2 foo/top.qcow2 qemu-img: Did not find '[...]/foo/mid.qcow2' in the backing chain of 'foo/top.qcow2' After this patch: $ ./qemu-img commit -b mid.qcow2 foo/top.qcow2 Image committed. $ ./qemu-img commit -b foo/mid.qcow2 foo/top.qcow2 qemu-img: Did not find 'foo/mid.qcow2' in the backing chain of 'foo/top.qcow2' $ ./qemu-img commit -b $PWD/foo/mid.qcow2 foo/top.qcow2 Image committed. With this change, bdrv_find_backing_image() must look at whether the user has overridden a BDS's backing file. If so, it can no longer use bs->backing_file, but must instead compare the given filename against the backing node's filename directly. Note that this changes the QAPI output for a node's backing_file. We had very inconsistent output there (sometimes what the image header said, sometimes the actual filename of the backing image). This inconsistent output was effectively useless, so we have to decide one way or the other. Considering that bs->backing_file usually at runtime contained the path to the image relative to qemu's CWD (or absolute), this patch changes QAPI's backing_file to always report the bs->backing->bs->filename from now on. If you want to receive the image header information, you have to refer to full-backing-filename. This necessitates a change to iotest 228. The interesting information it really wanted is the image header, and it can get that now, but it has to use full-backing-filename instead of backing_file. Because of this patch's changes to bs->backing_file's behavior, we also need some reference output changes. Along with the changes to bs->backing_file, stop updating BDS.backing_format in bdrv_backing_attach() as well. This necessitates a change to the reference output of iotest 191. iotest 245 changes in behavior: With the backing node no longer overriding the parent node's backing_file string, you can now omit the @backing option when reopening a node with neither a default nor a current backing file even if it used to have a backing node at some point. Signed-off-by: Max Reitz --- include/block/block_int.h | 19 ++++++++++++++----- block.c | 35 ++++++++++++++++++++++++++++------- block/qapi.c | 7 ++++--- tests/qemu-iotests/191.out | 1 - tests/qemu-iotests/228 | 6 +++--- tests/qemu-iotests/228.out | 6 +++--- tests/qemu-iotests/245 | 4 +++- 7 files changed, 55 insertions(+), 23 deletions(-) diff --git a/include/block/block_int.h b/include/block/block_int.h index 42ee2fcf7f..993bafc090 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -784,11 +784,20 @@ struct BlockDriverState { bool walking_aio_notifiers; /* to make removal during iteration safe */ char filename[PATH_MAX]; - char backing_file[PATH_MAX]; /* if non zero, the image is a diff of - this file image */ - /* The backing filename indicated by the image header; if we ever - * open this file, then this is replaced by the resulting BDS's - * filename (i.e. after a bdrv_refresh_filename() run). */ + /* + * If not empty, this image is a diff in relation to backing_file. + * Note that this is the name given in the image header and + * therefore may or may not be equal to .backing->bs->filename. + * If this field contains a relative path, it is to be resolved + * relatively to the overlay's location. + */ + char backing_file[PATH_MAX]; + /* + * The backing filename indicated by the image header. Contrary + * to backing_file, if we ever open this file, auto_backing_file + * is replaced by the resulting BDS's filename (i.e. after a + * bdrv_refresh_filename() run). + */ char auto_backing_file[PATH_MAX]; char backing_format[16]; /* if non-zero and backing_file exists */ diff --git a/block.c b/block.c index 4858d3e718..88533fa0d3 100644 --- a/block.c +++ b/block.c @@ -78,6 +78,8 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, const BdrvChildRole *child_role, Error **errp); +static bool bdrv_backing_overridden(BlockDriverState *bs); + /* If non-zero, use only whitelisted block drivers */ static int use_bdrv_whitelist; @@ -1065,10 +1067,6 @@ static void bdrv_backing_attach(BdrvChild *c) bdrv_refresh_filename(backing_hd); parent->open_flags &= ~BDRV_O_NO_BACKING; - pstrcpy(parent->backing_file, sizeof(parent->backing_file), - backing_hd->filename); - pstrcpy(parent->backing_format, sizeof(parent->backing_format), - backing_hd->drv ? backing_hd->drv->format_name : ""); bdrv_op_block_all(backing_hd, parent->backing_blocker); /* Otherwise we won't be able to commit or stream */ @@ -5294,6 +5292,7 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, char *backing_file_full = NULL; char *filename_tmp = NULL; int is_protocol = 0; + bool filenames_refreshed = false; BlockDriverState *curr_bs = NULL; BlockDriverState *retval = NULL; @@ -5318,9 +5317,31 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, { BlockDriverState *bs_below = bdrv_backing_chain_next(curr_bs); - /* If either of the filename paths is actually a protocol, then - * compare unmodified paths; otherwise make paths relative */ - if (is_protocol || path_has_protocol(curr_bs->backing_file)) { + if (bdrv_backing_overridden(curr_bs)) { + /* + * If the backing file was overridden, we can only compare + * directly against the backing node's filename. + */ + + if (!filenames_refreshed) { + /* + * This will automatically refresh all of the + * filenames in the rest of the backing chain, so we + * only need to do this once. + */ + bdrv_refresh_filename(bs_below); + filenames_refreshed = true; + } + + if (strcmp(backing_file, bs_below->filename) == 0) { + retval = bs_below; + break; + } + } else if (is_protocol || path_has_protocol(curr_bs->backing_file)) { + /* + * If either of the filename paths is actually a protocol, then + * compare unmodified paths; otherwise make paths relative. + */ char *backing_file_full_ret; if (strcmp(backing_file, curr_bs->backing_file) == 0) { diff --git a/block/qapi.c b/block/qapi.c index 4f59ac1c0f..751c3e695a 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -45,7 +45,7 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk, BlockDriverState *bs, Error **errp) { ImageInfo **p_image_info; - BlockDriverState *bs0; + BlockDriverState *bs0, *backing; BlockDeviceInfo *info; if (!bs->drv) { @@ -74,9 +74,10 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk, info->node_name = g_strdup(bs->node_name); } - if (bs->backing_file[0]) { + backing = bdrv_filtered_cow_bs(bs); + if (backing) { info->has_backing_file = true; - info->backing_file = g_strdup(bs->backing_file); + info->backing_file = g_strdup(backing->filename); } if (!QLIST_EMPTY(&bs->dirty_bitmaps)) { diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out index 3fc92bb56e..0b3c216b0c 100644 --- a/tests/qemu-iotests/191.out +++ b/tests/qemu-iotests/191.out @@ -605,7 +605,6 @@ wrote 65536/65536 bytes at offset 1048576 "backing-filename": "TEST_DIR/t.IMGFMT.base", "dirty-flag": false }, - "backing-filename-format": "IMGFMT", "virtual-size": 67108864, "filename": "TEST_DIR/t.IMGFMT.ovl3", "cluster-size": 65536, diff --git a/tests/qemu-iotests/228 b/tests/qemu-iotests/228 index 9a50afd205..a1f3187212 100755 --- a/tests/qemu-iotests/228 +++ b/tests/qemu-iotests/228 @@ -34,7 +34,7 @@ def log_node_info(node): log('bs->filename: ' + node['image']['filename'], filters=[filter_testfiles, filter_imgfmt]) - log('bs->backing_file: ' + node['backing_file'], + log('bs->backing_file: ' + node['image']['full-backing-filename'], filters=[filter_testfiles, filter_imgfmt]) if 'backing-image' in node['image']: @@ -70,8 +70,8 @@ with iotests.FilePath('base.img') as base_img_path, \ }, filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) - # Filename should be plain, and the backing filename should not - # contain the "file:" prefix + # Filename should be plain, and the backing node filename should + # not contain the "file:" prefix log_node_info(vm.node_info('node0')) vm.qmp_log('blockdev-del', node_name='node0') diff --git a/tests/qemu-iotests/228.out b/tests/qemu-iotests/228.out index 4217df24fe..8c82009abe 100644 --- a/tests/qemu-iotests/228.out +++ b/tests/qemu-iotests/228.out @@ -4,7 +4,7 @@ {"return": {}} bs->filename: TEST_DIR/PID-top.img -bs->backing_file: TEST_DIR/PID-base.img +bs->backing_file: file:TEST_DIR/PID-base.img bs->backing->bs->filename: TEST_DIR/PID-base.img {"execute": "blockdev-del", "arguments": {"node-name": "node0"}} @@ -41,7 +41,7 @@ bs->backing->bs->filename: TEST_DIR/PID-base.img {"return": {}} bs->filename: TEST_DIR/PID-top.img -bs->backing_file: TEST_DIR/PID-base.img +bs->backing_file: file:TEST_DIR/PID-base.img bs->backing->bs->filename: TEST_DIR/PID-base.img {"execute": "blockdev-del", "arguments": {"node-name": "node0"}} @@ -55,7 +55,7 @@ bs->backing->bs->filename: TEST_DIR/PID-base.img {"return": {}} bs->filename: json:{"backing": {"driver": "null-co"}, "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top.img"}} -bs->backing_file: null-co:// +bs->backing_file: TEST_DIR/PID-base.img bs->backing->bs->filename: null-co:// {"execute": "blockdev-del", "arguments": {"node-name": "node0"}} diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245 index bc1ceb9792..049ef6a71f 100644 --- a/tests/qemu-iotests/245 +++ b/tests/qemu-iotests/245 @@ -722,7 +722,9 @@ class TestBlockdevReopen(iotests.QMPTestCase): # Detach hd2 from hd0. self.reopen(opts, {'backing': None}) - self.reopen(opts, {}, "backing is missing for 'hd0'") + + # Without a backing file, we can omit 'backing' again + self.reopen(opts) # Remove both hd0 and hd2 result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd0') From patchwork Fri Aug 9 16:14:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087281 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 61A2513AC for ; Fri, 9 Aug 2019 16:31:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4C49120069 for ; Fri, 9 Aug 2019 16:31:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3ECE920134; Fri, 9 Aug 2019 16:31:20 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D1BAE20069 for ; Fri, 9 Aug 2019 16:31:19 +0000 (UTC) Received: from localhost ([::1]:32892 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7nT-0005W2-29 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:31:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57772) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7YT-00048g-21 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7YS-0004kr-3P for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48348) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7YN-0004iH-Th; Fri, 09 Aug 2019 12:15:44 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1A01E30A5416; Fri, 9 Aug 2019 16:15:43 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id AB7E860605; Fri, 9 Aug 2019 16:15:42 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:14:03 +0200 Message-Id: <20190809161407.11920-39-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Fri, 09 Aug 2019 16:15:43 +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 v6 38/42] iotests: Let complete_and_wait() work with commit X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP complete_and_wait() and wait_ready() currently only work for mirror jobs. Let them work for active commit jobs, too. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/iotests.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 84438e837c..3ef846d1dc 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -761,8 +761,12 @@ class QMPTestCase(unittest.TestCase): def wait_ready(self, drive='drive0'): '''Wait until a block job BLOCK_JOB_READY event''' - f = {'data': {'type': 'mirror', 'device': drive } } - event = self.vm.event_wait(name='BLOCK_JOB_READY', match=f) + event = self.vm.events_wait([ + ('BLOCK_JOB_READY', + {'data': {'type': 'mirror', 'device': drive } }), + ('BLOCK_JOB_READY', + {'data': {'type': 'commit', 'device': drive } }) + ]) def wait_ready_and_cancel(self, drive='drive0'): self.wait_ready(drive=drive) @@ -780,7 +784,7 @@ class QMPTestCase(unittest.TestCase): self.assert_qmp(result, 'return', {}) event = self.wait_until_completed(drive=drive) - self.assert_qmp(event, 'data/type', 'mirror') + self.assertTrue(event['data']['type'] in ['mirror', 'commit']) def pause_wait(self, job_id='job0'): with Timeout(1, "Timeout waiting for job to pause"): From patchwork Fri Aug 9 16:14:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087243 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 6140E14D5 for ; Fri, 9 Aug 2019 16:26:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4CC68201F5 for ; Fri, 9 Aug 2019 16:26:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 404BA201F3; Fri, 9 Aug 2019 16:26:01 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A95F6201BC for ; Fri, 9 Aug 2019 16:26:00 +0000 (UTC) Received: from localhost ([::1]:32778 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7iJ-0001Ye-Ru for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:25:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57807) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7YV-0004G2-9E for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7YT-0004ll-QU for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:51 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50266) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7YQ-0004j8-8s; Fri, 09 Aug 2019 12:15:46 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8AE44308FFB1; Fri, 9 Aug 2019 16:15:45 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id EA94610013A1; Fri, 9 Aug 2019 16:15:44 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:14:04 +0200 Message-Id: <20190809161407.11920-40-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Fri, 09 Aug 2019 16:15:45 +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 v6 39/42] iotests: Add filter commit test cases X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch adds some tests on how commit copes with filter nodes. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/040 | 177 +++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/040.out | 4 +- 2 files changed, 179 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040 index 6db9abf8e6..a0a0db8889 100755 --- a/tests/qemu-iotests/040 +++ b/tests/qemu-iotests/040 @@ -428,5 +428,182 @@ class TestReopenOverlay(ImageCommitTestCase): def test_reopen_overlay(self): self.run_commit_test(self.img1, self.img0) +class TestCommitWithFilters(iotests.QMPTestCase): + img0 = os.path.join(iotests.test_dir, '0.img') + img1 = os.path.join(iotests.test_dir, '1.img') + img2 = os.path.join(iotests.test_dir, '2.img') + img3 = os.path.join(iotests.test_dir, '3.img') + + def setUp(self): + qemu_img('create', '-f', iotests.imgfmt, self.img0, '64M') + qemu_img('create', '-f', iotests.imgfmt, self.img1, '64M') + qemu_img('create', '-f', iotests.imgfmt, self.img2, '64M') + qemu_img('create', '-f', iotests.imgfmt, self.img3, '64M') + + qemu_io('-f', iotests.imgfmt, '-c', 'write -P 1 0M 1M', self.img0) + qemu_io('-f', iotests.imgfmt, '-c', 'write -P 2 1M 1M', self.img1) + qemu_io('-f', iotests.imgfmt, '-c', 'write -P 3 2M 1M', self.img2) + qemu_io('-f', iotests.imgfmt, '-c', 'write -P 4 3M 1M', self.img3) + + # Distributions of the patterns in the files; this is checked + # by tearDown() and should be changed by the test cases as is + # necessary + self.pattern_files = [self.img0, self.img1, self.img2, self.img3] + + self.vm = iotests.VM() + self.vm.launch() + self.has_quit = False + + result = self.vm.qmp('object-add', qom_type='throttle-group', id='tg') + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('blockdev-add', **{ + 'node-name': 'top-filter', + 'driver': 'throttle', + 'throttle-group': 'tg', + 'file': { + 'node-name': 'cow-3', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': self.img3 + }, + 'backing': { + 'node-name': 'cow-2', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': self.img2 + }, + 'backing': { + 'node-name': 'cow-1', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': self.img1 + }, + 'backing': { + 'node-name': 'bottom-filter', + 'driver': 'throttle', + 'throttle-group': 'tg', + 'file': { + 'node-name': 'cow-0', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': self.img0 + } + } + } + } + } + } + }) + self.assert_qmp(result, 'return', {}) + + def tearDown(self): + self.vm.shutdown(has_quit=self.has_quit) + + for index in range(len(self.pattern_files)): + result = qemu_io('-f', iotests.imgfmt, + '-c', 'read -P %i %iM 1M' % (index + 1, index), + self.pattern_files[index]) + self.assertFalse('Pattern verification failed' in result) + + os.remove(self.img3) + os.remove(self.img2) + os.remove(self.img1) + os.remove(self.img0) + + # Filters make for funny filenames, so we cannot just use + # self.imgX to get them + def get_filename(self, node): + return self.vm.node_info(node)['image']['filename'] + + def test_filterless_commit(self): + self.assert_no_active_block_jobs() + result = self.vm.qmp('block-commit', + job_id='commit', + device='top-filter', + top_node='cow-2', + base_node='cow-1') + self.assert_qmp(result, 'return', {}) + self.wait_until_completed(drive='commit') + + self.assertIsNotNone(self.vm.node_info('cow-3')) + self.assertIsNone(self.vm.node_info('cow-2')) + self.assertIsNotNone(self.vm.node_info('cow-1')) + + # 2 has been comitted into 1 + self.pattern_files[2] = self.img1 + + def test_commit_through_filter(self): + self.assert_no_active_block_jobs() + result = self.vm.qmp('block-commit', + job_id='commit', + device='top-filter', + top_node='cow-1', + base_node='cow-0') + self.assert_qmp(result, 'return', {}) + self.wait_until_completed(drive='commit') + + self.assertIsNotNone(self.vm.node_info('cow-2')) + self.assertIsNone(self.vm.node_info('cow-1')) + self.assertIsNone(self.vm.node_info('bottom-filter')) + self.assertIsNotNone(self.vm.node_info('cow-0')) + + # 1 has been comitted into 0 + self.pattern_files[1] = self.img0 + + def test_filtered_active_commit_with_filter(self): + # Add a device, so the commit job finds a parent it can change + # to point to the base node (so we can test that top-filter is + # dropped from the graph) + result = self.vm.qmp('device_add', id='drv0', driver='virtio-blk', + drive='top-filter') + self.assert_qmp(result, 'return', {}) + + # Try to release our reference to top-filter; that should not + # work because drv0 uses it + result = self.vm.qmp('blockdev-del', node_name='top-filter') + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', 'Node top-filter is in use') + + self.assert_no_active_block_jobs() + result = self.vm.qmp('block-commit', + job_id='commit', + device='top-filter', + base_node='cow-2') + self.assert_qmp(result, 'return', {}) + self.complete_and_wait(drive='commit') + + # Try to release our reference to top-filter again + result = self.vm.qmp('blockdev-del', node_name='top-filter') + self.assert_qmp(result, 'return', {}) + + self.assertIsNone(self.vm.node_info('top-filter')) + self.assertIsNone(self.vm.node_info('cow-3')) + self.assertIsNotNone(self.vm.node_info('cow-2')) + + # 3 has been comitted into 2 + self.pattern_files[3] = self.img2 + + def test_filtered_active_commit_without_filter(self): + self.assert_no_active_block_jobs() + result = self.vm.qmp('block-commit', + job_id='commit', + device='top-filter', + top_node='cow-3', + base_node='cow-2') + self.assert_qmp(result, 'return', {}) + self.complete_and_wait(drive='commit') + + self.assertIsNotNone(self.vm.node_info('top-filter')) + self.assertIsNone(self.vm.node_info('cow-3')) + self.assertIsNotNone(self.vm.node_info('cow-2')) + + # 3 has been comitted into 2 + self.pattern_files[3] = self.img2 + if __name__ == '__main__': iotests.main(supported_fmts=['qcow2', 'qed']) diff --git a/tests/qemu-iotests/040.out b/tests/qemu-iotests/040.out index 220a5fa82c..fe58934d7a 100644 --- a/tests/qemu-iotests/040.out +++ b/tests/qemu-iotests/040.out @@ -1,5 +1,5 @@ -............................................... +................................................... ---------------------------------------------------------------------- -Ran 47 tests +Ran 51 tests OK From patchwork Fri Aug 9 16:14:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087285 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 70DD6746 for ; Fri, 9 Aug 2019 16:32:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5E0A7200CB for ; Fri, 9 Aug 2019 16:32:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 509A820134; Fri, 9 Aug 2019 16:32:08 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C933A200CB for ; Fri, 9 Aug 2019 16:32:07 +0000 (UTC) Received: from localhost ([::1]:32908 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7oF-0007TQ-4Z for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:32:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57834) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7YX-0004MA-3G for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7YV-0004mu-Ma for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:53 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51832) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7YS-0004kx-Kw; Fri, 09 Aug 2019 12:15:48 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EF13D316EFEC; Fri, 9 Aug 2019 16:15:47 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5F3CD60BF7; Fri, 9 Aug 2019 16:15:47 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:14:05 +0200 Message-Id: <20190809161407.11920-41-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Fri, 09 Aug 2019 16:15:48 +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 v6 40/42] iotests: Add filter mirror test cases X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch adds some test cases how mirroring relates to filters. One of them tests what happens when you mirror off a filtered COW node, two others use the mirror filter node as basically our only example of an implicitly created filter node so far (besides the commit filter). Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/041 | 146 ++++++++++++++++++++++++++++++++++++- tests/qemu-iotests/041.out | 4 +- 2 files changed, 147 insertions(+), 3 deletions(-) diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index 0c1432f189..c2b5299f62 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -20,8 +20,9 @@ import time import os +import json import iotests -from iotests import qemu_img, qemu_io +from iotests import qemu_img, qemu_img_pipe, qemu_io backing_img = os.path.join(iotests.test_dir, 'backing.img') target_backing_img = os.path.join(iotests.test_dir, 'target-backing.img') @@ -1191,5 +1192,148 @@ class TestReplaces(iotests.QMPTestCase): os.remove(test_img) os.remove(target_img) +# Tests for mirror with filters (and how the mirror filter behaves, as +# an example for an implicit filter) +class TestFilters(iotests.QMPTestCase): + def setUp(self): + qemu_img('create', '-f', iotests.imgfmt, backing_img, '1M') + qemu_img('create', '-f', iotests.imgfmt, '-b', backing_img, test_img) + qemu_img('create', '-f', iotests.imgfmt, '-b', backing_img, target_img) + + qemu_io('-c', 'write -P 1 0 512k', backing_img) + qemu_io('-c', 'write -P 2 512k 512k', test_img) + + self.vm = iotests.VM() + self.vm.launch() + + result = self.vm.qmp('blockdev-add', **{ + 'node-name': 'target', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': target_img + }, + 'backing': None + }) + self.assert_qmp(result, 'return', {}) + + self.filterless_chain = { + 'node-name': 'source', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': test_img + }, + 'backing': { + 'node-name': 'backing', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': backing_img + } + } + } + + def tearDown(self): + self.vm.shutdown() + + os.remove(test_img) + os.remove(target_img) + os.remove(backing_img) + + def test_cor(self): + result = self.vm.qmp('blockdev-add', **{ + 'node-name': 'filter', + 'driver': 'copy-on-read', + 'file': self.filterless_chain + }) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('blockdev-mirror', + job_id='mirror', + device='filter', + target='target', + sync='top') + self.assert_qmp(result, 'return', {}) + + self.complete_and_wait('mirror') + + self.vm.qmp('blockdev-del', node_name='target') + + target_map = qemu_img_pipe('map', '--output=json', target_img) + target_map = json.loads(target_map) + + assert target_map[0]['start'] == 0 + assert target_map[0]['length'] == 512 * 1024 + assert target_map[0]['depth'] == 1 + + assert target_map[1]['start'] == 512 * 1024 + assert target_map[1]['length'] == 512 * 1024 + assert target_map[1]['depth'] == 0 + + def test_implicit_mirror_filter(self): + result = self.vm.qmp('blockdev-add', **self.filterless_chain) + self.assert_qmp(result, 'return', {}) + + # We need this so we can query from above the mirror node + result = self.vm.qmp('device_add', + driver='virtio-blk', + id='virtio', + bus='pci.0', + drive='source') + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('blockdev-mirror', + job_id='mirror', + device='source', + target='target', + sync='top') + self.assert_qmp(result, 'return', {}) + + # The mirror filter is now an implicit node, so it should be + # invisible when querying the backing chain + device_info = self.vm.qmp('query-block')['return'][0] + assert device_info['qdev'] == '/machine/peripheral/virtio/virtio-backend' + + assert device_info['inserted']['node-name'] == 'source' + + image_info = device_info['inserted']['image'] + assert image_info['filename'] == test_img + assert image_info['backing-image']['filename'] == backing_img + + self.complete_and_wait('mirror') + + def test_explicit_mirror_filter(self): + # Same test as above, but this time we give the mirror filter + # a node-name so it will not be invisible + result = self.vm.qmp('blockdev-add', **self.filterless_chain) + self.assert_qmp(result, 'return', {}) + + # We need this so we can query from above the mirror node + result = self.vm.qmp('device_add', + driver='virtio-blk', + id='virtio', + bus='pci.0', + drive='source') + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('blockdev-mirror', + job_id='mirror', + device='source', + target='target', + sync='top', + filter_node_name='mirror-filter') + self.assert_qmp(result, 'return', {}) + + # With a node-name given to it, the mirror filter should now + # be visible + device_info = self.vm.qmp('query-block')['return'][0] + assert device_info['qdev'] == '/machine/peripheral/virtio/virtio-backend' + + assert device_info['inserted']['node-name'] == 'mirror-filter' + + self.complete_and_wait('mirror') + + if __name__ == '__main__': iotests.main(supported_fmts=['qcow2', 'qed']) diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out index 2c448b4239..ffc779b4d1 100644 --- a/tests/qemu-iotests/041.out +++ b/tests/qemu-iotests/041.out @@ -1,5 +1,5 @@ -.......................................................................................... +............................................................................................. ---------------------------------------------------------------------- -Ran 90 tests +Ran 93 tests OK From patchwork Fri Aug 9 16:14:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087321 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 C10A31850 for ; Fri, 9 Aug 2019 16:34:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AFCFA1FE82 for ; Fri, 9 Aug 2019 16:34:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A430C201B0; Fri, 9 Aug 2019 16:34:24 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4355C1FE82 for ; Fri, 9 Aug 2019 16:34:24 +0000 (UTC) Received: from localhost ([::1]:32936 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7qR-0002IH-H2 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:34:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57856) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7YZ-0004U7-05 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7YX-0004oG-U3 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45836) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7YV-0004mK-Eo; Fri, 09 Aug 2019 12:15:51 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BFE2981F31; Fri, 9 Aug 2019 16:15:50 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C6DE95D9C3; Fri, 9 Aug 2019 16:15:49 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:14:06 +0200 Message-Id: <20190809161407.11920-42-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Fri, 09 Aug 2019 16:15:50 +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 v6 41/42] iotests: Add test for commit in sub directory X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add a test for committing an overlay in a sub directory to one of the images in its backing chain, using both relative and absolute filenames. Signed-off-by: Max Reitz --- tests/qemu-iotests/020 | 36 ++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/020.out | 10 ++++++++++ 2 files changed, 46 insertions(+) diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020 index 6b0ebb37d2..94633c3a32 100755 --- a/tests/qemu-iotests/020 +++ b/tests/qemu-iotests/020 @@ -31,6 +31,11 @@ _cleanup() _cleanup_test_img rm -f "$TEST_IMG.base" rm -f "$TEST_IMG.orig" + + rm -f "$TEST_DIR/subdir/t.$IMGFMT.base" + rm -f "$TEST_DIR/subdir/t.$IMGFMT.mid" + rm -f "$TEST_DIR/subdir/t.$IMGFMT" + rmdir "$TEST_DIR/subdir" &> /dev/null } trap "_cleanup; exit \$status" 0 1 2 3 15 @@ -133,6 +138,37 @@ $QEMU_IO -c 'writev 0 64k' "$TEST_IMG" | _filter_qemu_io $QEMU_IMG commit "$TEST_IMG" _cleanup + +echo +echo 'Testing commit in sub-directory with relative filenames' +echo + +pushd "$TEST_DIR" > /dev/null + +mkdir subdir + +TEST_IMG="subdir/t.$IMGFMT.base" _make_test_img 1M +TEST_IMG="subdir/t.$IMGFMT.mid" _make_test_img -b "t.$IMGFMT.base" +TEST_IMG="subdir/t.$IMGFMT" _make_test_img -b "t.$IMGFMT.mid" + +# Should work +$QEMU_IMG commit -b "t.$IMGFMT.mid" "subdir/t.$IMGFMT" + +# Might theoretically work, but does not in practice (we have to +# decide between this and the above; and since we always represent +# backing file names as relative to the overlay, we go for the above) +$QEMU_IMG commit -b "subdir/t.$IMGFMT.mid" "subdir/t.$IMGFMT" 2>&1 | \ + _filter_imgfmt + +# This should work as well +$QEMU_IMG commit -b "$TEST_DIR/subdir/t.$IMGFMT.mid" "subdir/t.$IMGFMT" + +popd > /dev/null + +# Now let's try with just absolute filenames +$QEMU_IMG commit -b "$TEST_DIR/subdir/t.$IMGFMT.mid" \ + "$TEST_DIR/subdir/t.$IMGFMT" + # success, all done echo "*** done" rm -f $seq.full diff --git a/tests/qemu-iotests/020.out b/tests/qemu-iotests/020.out index 4b722b2dd0..228c37dded 100644 --- a/tests/qemu-iotests/020.out +++ b/tests/qemu-iotests/020.out @@ -1094,4 +1094,14 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=json:{'driv wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) qemu-img: Block job failed: No space left on device + +Testing commit in sub-directory with relative filenames + +Formatting 'subdir/t.IMGFMT.base', fmt=IMGFMT size=1048576 +Formatting 'subdir/t.IMGFMT.mid', fmt=IMGFMT size=1048576 backing_file=t.IMGFMT.base +Formatting 'subdir/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=t.IMGFMT.mid +Image committed. +qemu-img: Did not find 'subdir/t.IMGFMT.mid' in the backing chain of 'subdir/t.IMGFMT' +Image committed. +Image committed. *** done From patchwork Fri Aug 9 16:14:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11087267 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 A51D914D5 for ; Fri, 9 Aug 2019 16:28:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9392A1FFCA for ; Fri, 9 Aug 2019 16:28:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 81B842023F; Fri, 9 Aug 2019 16:28:11 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1A3AC1FFCA for ; Fri, 9 Aug 2019 16:28:11 +0000 (UTC) Received: from localhost ([::1]:32828 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7kQ-000821-G5 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 09 Aug 2019 12:28:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57887) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hw7Yc-0004gN-Ce for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hw7Yb-0004pp-C0 for qemu-devel@nongnu.org; Fri, 09 Aug 2019 12:15:58 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48470) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hw7YZ-0004oa-1G; Fri, 09 Aug 2019 12:15:55 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5E3EE3058359; Fri, 9 Aug 2019 16:15:54 +0000 (UTC) Received: from localhost (unknown [10.40.205.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 94F245D772; Fri, 9 Aug 2019 16:15:52 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Fri, 9 Aug 2019 18:14:07 +0200 Message-Id: <20190809161407.11920-43-mreitz@redhat.com> In-Reply-To: <20190809161407.11920-1-mreitz@redhat.com> References: <20190809161407.11920-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Fri, 09 Aug 2019 16:15:54 +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 v6 42/42] iotests: Test committing to overridden backing X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/040 | 61 ++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/040.out | 4 +-- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040 index a0a0db8889..558fdb9a09 100755 --- a/tests/qemu-iotests/040 +++ b/tests/qemu-iotests/040 @@ -605,5 +605,66 @@ class TestCommitWithFilters(iotests.QMPTestCase): # 3 has been comitted into 2 self.pattern_files[3] = self.img2 +class TestCommitWithOverriddenBacking(iotests.QMPTestCase): + img_base_a = os.path.join(iotests.test_dir, 'base_a.img') + img_base_b = os.path.join(iotests.test_dir, 'base_b.img') + img_top = os.path.join(iotests.test_dir, 'top.img') + + def setUp(self): + qemu_img('create', '-f', iotests.imgfmt, self.img_base_a, '1M') + qemu_img('create', '-f', iotests.imgfmt, self.img_base_b, '1M') + qemu_img('create', '-f', iotests.imgfmt, '-b', self.img_base_a, \ + self.img_top) + + self.vm = iotests.VM() + self.vm.launch() + + # Use base_b instead of base_a as the backing of top + result = self.vm.qmp('blockdev-add', **{ + 'node-name': 'top', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': self.img_top + }, + 'backing': { + 'node-name': 'base', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': self.img_base_b + } + } + }) + self.assert_qmp(result, 'return', {}) + + def tearDown(self): + self.vm.shutdown() + os.remove(self.img_top) + os.remove(self.img_base_a) + os.remove(self.img_base_b) + + def test_commit_to_a(self): + # Try committing to base_a (which should fail, as top's + # backing image is base_b instead) + result = self.vm.qmp('block-commit', + job_id='commit', + device='top', + base=self.img_base_a) + self.assert_qmp(result, 'error/class', 'GenericError') + + def test_commit_to_b(self): + # Try committing to base_b (which should work, since that is + # actually top's backing image) + result = self.vm.qmp('block-commit', + job_id='commit', + device='top', + base=self.img_base_b) + self.assert_qmp(result, 'return', {}) + + self.vm.event_wait('BLOCK_JOB_READY') + self.vm.qmp('block-job-complete', device='commit') + self.vm.event_wait('BLOCK_JOB_COMPLETED') + if __name__ == '__main__': iotests.main(supported_fmts=['qcow2', 'qed']) diff --git a/tests/qemu-iotests/040.out b/tests/qemu-iotests/040.out index fe58934d7a..499af0e2ff 100644 --- a/tests/qemu-iotests/040.out +++ b/tests/qemu-iotests/040.out @@ -1,5 +1,5 @@ -................................................... +..................................................... ---------------------------------------------------------------------- -Ran 51 tests +Ran 53 tests OK