From nobody Tue Feb 10 01:32:44 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1589295583; cv=none; d=zohomail.com; s=zohoarc; b=T6xZKRke6epyEL3OSbKDbQYLGDVS/At37o5tIga5hNCofvzCwLE5DXTWEjQGTMfSHmq+TWwOtAdhshsFsJ0wJY76Y4m2h8l3uwpBNyfNNwap0deNJ+0ZlJ5uDV49+iwZw/92DBP1gy0F/wBue4Rot4mq7jItXlkWp9A16/RP7FU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1589295583; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=Cz7enbsa2nWcLDvJSYLqiuD1TA9o0ydVsr7jppDtfZw=; b=Pa3w35FTRmhyX9bcduwoeV753CRRiMzp49TxF0dO1FLDsX4+il0u5/bO2HPqAYRi5R9D3+BtpPaXdnEyrkpuf+M6/DgtDs1HsW1Da1zh+WmUog3rW53az2uQizPsSRjCNxYO90+q5Y9VkjpwSGJ+EsA9w3dOClJDqqnmR7LVbZ8= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1589295583942310.7431826077201; Tue, 12 May 2020 07:59:43 -0700 (PDT) Received: from localhost ([::1]:46202 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jYWNi-0000CB-IG for importer@patchew.org; Tue, 12 May 2020 10:59:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60258) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jYWHk-0004uI-OY; Tue, 12 May 2020 10:53:32 -0400 Received: from relay.sw.ru ([185.231.240.75]:45830) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jYWHh-0005oo-8J; Tue, 12 May 2020 10:53:32 -0400 Received: from dhcp-172-16-25-136.sw.ru ([172.16.25.136] helo=localhost.sw.ru) by relay.sw.ru with esmtp (Exim 4.92.3) (envelope-from ) id 1jYWHZ-0003c8-J5; Tue, 12 May 2020 17:53:21 +0300 From: Andrey Shinkevich To: qemu-block@nongnu.org Subject: [PATCH v3 07/15] commit: Deal with filters when blocking intermediate nodes Date: Tue, 12 May 2020 17:53:08 +0300 Message-Id: <1589295196-773454-8-git-send-email-andrey.shinkevich@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1589295196-773454-1-git-send-email-andrey.shinkevich@virtuozzo.com> References: <1589295196-773454-1-git-send-email-andrey.shinkevich@virtuozzo.com> Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.231.240.75; envelope-from=andrey.shinkevich@virtuozzo.com; helo=relay.sw.ru X-detected-operating-system: by eggs.gnu.org: First seen = 2020/05/12 10:53:25 X-ACL-Warn: Detected OS = Linux 3.1-3.10 X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action 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: kwolf@redhat.com, fam@euphon.net, vsementsov@virtuozzo.com, armbru@redhat.com, qemu-devel@nongnu.org, stefanha@redhat.com, andrey.shinkevich@virtuozzo.com, den@openvz.org, mreitz@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz 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 Signed-off-by: Andrey Shinkevich --- block/commit.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++--------= ---- 1 file changed, 60 insertions(+), 15 deletions(-) diff --git a/block/commit.c b/block/commit.c index e1f45a4..4df145d 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; @@ -153,7 +154,7 @@ static int coroutine_fn commit_run(Job *job, Error **er= rp) break; } /* Copy if allocated above the base */ - ret =3D bdrv_is_allocated_above(blk_bs(s->top), blk_bs(s->base), f= alse, + ret =3D bdrv_is_allocated_above(blk_bs(s->top), s->above_base, tru= e, offset, COMMIT_BUFFER_SIZE, &n); copy =3D (ret =3D=3D 1); trace_commit_one_iteration(s, offset, n, ret); @@ -253,15 +254,35 @@ void commit_start(const char *job_id, BlockDriverStat= e *bs, CommitBlockJob *s; BlockDriverState *iter; BlockDriverState *commit_top_bs =3D NULL; + BlockDriverState *filtered_base; Error *local_err =3D NULL; + int64_t base_size, top_size; + uint64_t perms, iter_shared_perms; int ret; =20 assert(top !=3D bs); - if (top =3D=3D base) { + if (bdrv_skip_rw_filters(top) =3D=3D bdrv_skip_rw_filters(base)) { error_setg(errp, "Invalid files for merge: top and base are the sa= me"); return; } =20 + base_size =3D bdrv_getlength(base); + if (base_size < 0) { + error_setg_errno(errp, -base_size, "Could not inquire base image s= ize"); + return; + } + + top_size =3D bdrv_getlength(top); + if (top_size < 0) { + error_setg_errno(errp, -top_size, "Could not inquire top image siz= e"); + return; + } + + perms =3D BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE; + if (base_size < top_size) { + perms |=3D BLK_PERM_RESIZE; + } + s =3D block_job_create(job_id, &commit_job_driver, NULL, bs, 0, BLK_PE= RM_ALL, speed, creation_flags, NULL, NULL, errp); if (!s) { @@ -301,17 +322,43 @@ void commit_start(const char *job_id, BlockDriverStat= e *bs, =20 s->commit_top_bs =3D commit_top_bs; =20 - /* 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 =3D top; iter !=3D base; iter =3D backing_bs(iter)) { - /* XXX BLK_PERM_WRITE needs to be allowed so we don't block oursel= ves - * at s->base (if writes are blocked for a node, they are also blo= cked - * for its backing file). The other options would be a second filt= er - * 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 =3D bdrv_find_overlay(top, base); + assert(s->above_base); + + /* + * The topmost node with + * bdrv_skip_rw_filters(filtered_base) =3D=3D bdrv_skip_rw_filters(bas= e) + */ + filtered_base =3D bdrv_filtered_cow_bs(s->above_base); + assert(bdrv_skip_rw_filters(filtered_base) =3D=3D 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 =3D BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE; + + for (iter =3D top; iter !=3D base; iter =3D bdrv_filtered_bs(iter)) { + if (iter =3D=3D filtered_base) { + /* + * From here on, all nodes are filters on the base. This + * allows us to share BLK_PERM_CONSISTENT_READ. + */ + iter_shared_perms |=3D BLK_PERM_CONSISTENT_READ; + } + ret =3D 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; } @@ -328,9 +375,7 @@ void commit_start(const char *job_id, BlockDriverState = *bs, } =20 s->base =3D 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); --=20 1.8.3.1