From nobody Tue Feb 10 23:01:08 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1506342627837806.9002282625476; Mon, 25 Sep 2017 05:30:27 -0700 (PDT) Received: from localhost ([::1]:42263 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwSWf-00052Q-Js for importer@patchew.org; Mon, 25 Sep 2017 08:30:17 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47221) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwSUn-0003VJ-OH for qemu-devel@nongnu.org; Mon, 25 Sep 2017 08:28:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dwSUm-00065G-L5 for qemu-devel@nongnu.org; Mon, 25 Sep 2017 08:28:21 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45286) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dwSUi-00062f-6w; Mon, 25 Sep 2017 08:28:16 -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 4CF4CC0587DE; Mon, 25 Sep 2017 12:28:15 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-119.ams2.redhat.com [10.36.116.119]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1370F70A10; Mon, 25 Sep 2017 12:28:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 4CF4CC0587DE Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kwolf@redhat.com From: Kevin Wolf To: qemu-block@nongnu.org Date: Mon, 25 Sep 2017 14:28:05 +0200 Message-Id: <20170925122808.14561-3-kwolf@redhat.com> In-Reply-To: <20170925122808.14561-1-kwolf@redhat.com> References: <20170925122808.14561-1-kwolf@redhat.com> 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.32]); Mon, 25 Sep 2017 12:28:15 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 2/5] commit: Support multiple roots above top node X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This changes the commit block job to support operation in a graph where there is more than a single active layer that references the top node. This involves inserting the commit filter node not only on the path between the given active node and the top node, but between the top node and all of its parents. On completion, bdrv_drop_intermediate() must consider all parents for updating the backing file link. These parents may be backing files themselves and such read-only; reopen them temporarily if necessary. Previously this was achieved by the bdrv_reopen() calls in the commit block job that made overlay_bs read-write for the whole duration of the block job, even though write access is only needed on completion. Now that we consider all parents, overlay_bs is meaningless. It is left in place in this commit, but we'll remove it soon. Signed-off-by: Kevin Wolf --- block.c | 68 ++++++++++++++++++++++++++++++++++--------------------= ---- block/commit.c | 2 +- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/block.c b/block.c index 7ac8cd521b..e57fab501d 100644 --- a/block.c +++ b/block.c @@ -985,14 +985,26 @@ static int bdrv_backing_update_filename(BdrvChild *c,= BlockDriverState *base, const char *filename, Error **errp) { BlockDriverState *parent =3D c->opaque; + int orig_flags =3D bdrv_get_flags(parent); int ret; =20 + if (!(orig_flags & BDRV_O_RDWR)) { + ret =3D bdrv_reopen(parent, orig_flags | BDRV_O_RDWR, errp); + if (ret < 0) { + return ret; + } + } + ret =3D bdrv_change_backing_file(parent, filename, base->drv ? base->drv->format_name : ""= ); if (ret < 0) { error_setg_errno(errp, ret, "Could not update backing file link"); } =20 + if (!(orig_flags & BDRV_O_RDWR)) { + bdrv_reopen(parent, orig_flags, NULL); + } + return ret; } =20 @@ -3482,7 +3494,7 @@ BlockDriverState *bdrv_find_base(BlockDriverState *bs) int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top, BlockDriverState *base, const char *backing_fil= e_str) { - BlockDriverState *new_top_bs =3D NULL; + BdrvChild *c, *next; Error *local_err =3D NULL; int ret =3D -EIO; =20 @@ -3492,42 +3504,42 @@ int bdrv_drop_intermediate(BlockDriverState *active= , BlockDriverState *top, goto exit; } =20 - new_top_bs =3D bdrv_find_overlay(active, top); - - if (new_top_bs =3D=3D NULL) { - /* we could not find the image above 'top', this is an error */ - goto exit; - } - - /* special case of new_top_bs->backing->bs already pointing to base - = nothing - * to do, no intermediate images */ - if (backing_bs(new_top_bs) =3D=3D base) { - ret =3D 0; - goto exit; - } - /* Make sure that base is in the backing chain of top */ if (!bdrv_chain_contains(top, base)) { goto exit; } =20 /* success - we can delete the intermediate states, and link top->base= */ - if (new_top_bs->backing->role->update_filename) { - backing_file_str =3D backing_file_str ? backing_file_str : base->f= ilename; - ret =3D new_top_bs->backing->role->update_filename(new_top_bs->bac= king, - base, backing_fil= e_str, - &local_err); - if (ret < 0) { - bdrv_set_backing_hd(new_top_bs, top, &error_abort); + backing_file_str =3D backing_file_str ? backing_file_str : base->filen= ame; + + QLIST_FOREACH_SAFE(c, &top->parents, next_parent, next) { + /* Check whether we are allowed to switch c from top to base */ + GSList *ignore_children =3D g_slist_prepend(NULL, c); + bdrv_check_update_perm(base, NULL, c->perm, c->shared_perm, + ignore_children, &local_err); + if (local_err) { + ret =3D -EPERM; + error_report_err(local_err); goto exit; } - } + g_slist_free(ignore_children); =20 - bdrv_set_backing_hd(new_top_bs, base, &local_err); - if (local_err) { - ret =3D -EPERM; - error_report_err(local_err); - goto exit; + /* If so, update the backing file path in the image file */ + if (c->role->update_filename) { + ret =3D c->role->update_filename(c, base, backing_file_str, + &local_err); + if (ret < 0) { + bdrv_abort_perm_update(base); + error_report_err(local_err); + goto exit; + } + } + + /* Do the actual switch in the in-memory graph. + * Completes bdrv_check_update_perm() transaction internally. */ + bdrv_ref(base); + bdrv_replace_child(c, base); + bdrv_unref(top); } =20 ret =3D 0; diff --git a/block/commit.c b/block/commit.c index 8f0e83578a..610e1cd8f5 100644 --- a/block/commit.c +++ b/block/commit.c @@ -350,7 +350,7 @@ void commit_start(const char *job_id, BlockDriverState = *bs, error_propagate(errp, local_err); goto fail; } - bdrv_set_backing_hd(overlay_bs, commit_top_bs, &local_err); + bdrv_replace_node(top, commit_top_bs, &local_err); if (local_err) { bdrv_unref(commit_top_bs); commit_top_bs =3D NULL; --=20 2.13.5