From nobody Tue Apr 15 03:09:24 2025 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 (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1506436966359981.6434543553952; Tue, 26 Sep 2017 07:42:46 -0700 (PDT) Received: from localhost ([::1]:47910 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwr4C-0001cl-VD for importer@patchew.org; Tue, 26 Sep 2017 10:42:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33068) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwqkh-0001ic-Ir for qemu-devel@nongnu.org; Tue, 26 Sep 2017 10:22:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dwqkg-0005ae-62 for qemu-devel@nongnu.org; Tue, 26 Sep 2017 10:22:23 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46826) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dwqkU-0005Q6-Al; Tue, 26 Sep 2017 10:22: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 1A474267CD; Tue, 26 Sep 2017 14:22:09 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-39.ams2.redhat.com [10.36.117.39]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0404466D4E; Tue, 26 Sep 2017 14:22:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 1A474267CD Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kwolf@redhat.com From: Kevin Wolf To: qemu-block@nongnu.org Date: Tue, 26 Sep 2017 16:21:24 +0200 Message-Id: <20170926142133.2498-16-kwolf@redhat.com> In-Reply-To: <20170926142133.2498-1-kwolf@redhat.com> References: <20170926142133.2498-1-kwolf@redhat.com> 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]); Tue, 26 Sep 2017 14:22:09 +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] [PULL 15/24] block: Base permissions on rw state after reopen 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, peter.maydell@linaro.org, qemu-devel@nongnu.org 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" When new permissions are calculated during bdrv_reopen(), they need to be based on the state of the graph as it will be after the reopen has completed, not on the current state of the involved nodes. This patch makes bdrv_is_writable() optionally accept a BlockReopenQueue from which the new flags are taken. This is then used for determining the new bs->file permissions of format drivers as soon as we add the code to actually pass a non-NULL reopen queue to the .bdrv_child_perm callbacks. While moving bdrv_is_writable(), make it static. It isn't used outside block.c. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- include/block/block.h | 1 - block.c | 52 ++++++++++++++++++++++++++++++++++++-----------= ---- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index 2ad18775af..082eb2cd9c 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -435,7 +435,6 @@ int bdrv_is_allocated_above(BlockDriverState *top, Bloc= kDriverState *base, int64_t offset, int64_t bytes, int64_t *pnum); =20 bool bdrv_is_read_only(BlockDriverState *bs); -bool bdrv_is_writable(BlockDriverState *bs); int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, bool ignore_allow_rdw, Error **errp); int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp); diff --git a/block.c b/block.c index 0b499fda4c..ed8d51dd42 100644 --- a/block.c +++ b/block.c @@ -239,12 +239,6 @@ bool bdrv_is_read_only(BlockDriverState *bs) return bs->read_only; } =20 -/* Returns whether the image file can be written to right now */ -bool bdrv_is_writable(BlockDriverState *bs) -{ - return !bdrv_is_read_only(bs) && !(bs->open_flags & BDRV_O_INACTIVE); -} - int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, bool ignore_allow_rdw, Error **errp) { @@ -1537,6 +1531,41 @@ static int bdrv_child_check_perm(BdrvChild *c, Block= ReopenQueue *q, static void bdrv_child_abort_perm_update(BdrvChild *c); static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shar= ed); =20 +typedef struct BlockReopenQueueEntry { + bool prepared; + BDRVReopenState state; + QSIMPLEQ_ENTRY(BlockReopenQueueEntry) entry; +} BlockReopenQueueEntry; + +/* + * Return the flags that @bs will have after the reopens in @q have + * successfully completed. If @q is NULL (or @bs is not contained in @q), + * return the current flags. + */ +static int bdrv_reopen_get_flags(BlockReopenQueue *q, BlockDriverState *bs) +{ + BlockReopenQueueEntry *entry; + + if (q !=3D NULL) { + QSIMPLEQ_FOREACH(entry, q, entry) { + if (entry->state.bs =3D=3D bs) { + return entry->state.flags; + } + } + } + + return bs->open_flags; +} + +/* Returns whether the image file can be written to after the reopen queue= @q + * has been successfully applied, or right now if @q is NULL. */ +static bool bdrv_is_writable(BlockDriverState *bs, BlockReopenQueue *q) +{ + int flags =3D bdrv_reopen_get_flags(q, bs); + + return (flags & (BDRV_O_RDWR | BDRV_O_INACTIVE)) =3D=3D BDRV_O_RDWR; +} + static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_= bs, BdrvChild *c, const BdrvChildRole *role, BlockReopenQueue *reopen_queue, @@ -1574,7 +1603,7 @@ static int bdrv_check_perm(BlockDriverState *bs, Bloc= kReopenQueue *q, =20 /* Write permissions never work with read-only images */ if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) && - !bdrv_is_writable(bs)) + !bdrv_is_writable(bs, q)) { error_setg(errp, "Block node is read-only"); return -EPERM; @@ -1864,8 +1893,7 @@ void bdrv_format_default_perms(BlockDriverState *bs, = BdrvChild *c, &perm, &shared); =20 /* Format drivers may touch metadata even if the guest doesn't wri= te */ - /* TODO Take flags from reopen_queue */ - if (bdrv_is_writable(bs)) { + if (bdrv_is_writable(bs, reopen_queue)) { perm |=3D BLK_PERM_WRITE | BLK_PERM_RESIZE; } =20 @@ -2642,12 +2670,6 @@ BlockDriverState *bdrv_open(const char *filename, co= nst char *reference, NULL, errp); } =20 -typedef struct BlockReopenQueueEntry { - bool prepared; - BDRVReopenState state; - QSIMPLEQ_ENTRY(BlockReopenQueueEntry) entry; -} BlockReopenQueueEntry; - /* * Adds a BlockDriverState to a simple queue for an atomic, transactional * reopen of multiple devices. --=20 2.13.5