From nobody Thu Dec 18 17:58:59 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.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; Authentication-Results: mx.zohomail.com; spf=pass (zoho.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=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1552414742127401.4281220397846; Tue, 12 Mar 2019 11:19:02 -0700 (PDT) Received: from localhost ([127.0.0.1]:57233 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h3lzM-00007d-W8 for importer@patchew.org; Tue, 12 Mar 2019 14:18:57 -0400 Received: from eggs.gnu.org ([209.51.188.92]:57020) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h3lFC-0001OY-7C for qemu-devel@nongnu.org; Tue, 12 Mar 2019 13:31:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h3lF9-0000Ss-QT for qemu-devel@nongnu.org; Tue, 12 Mar 2019 13:31:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41798) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h3lF5-0000N0-Ty; Tue, 12 Mar 2019 13:31:08 -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 1B7A188287; Tue, 12 Mar 2019 17:31:07 +0000 (UTC) Received: from linux.fritz.box.com (ovpn-117-52.ams2.redhat.com [10.36.117.52]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0E02660BF7; Tue, 12 Mar 2019 17:31:05 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Tue, 12 Mar 2019 18:30:22 +0100 Message-Id: <20190312173025.3843-26-kwolf@redhat.com> In-Reply-To: <20190312173025.3843-1-kwolf@redhat.com> References: <20190312173025.3843-1-kwolf@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.27]); Tue, 12 Mar 2019 17:31:07 +0000 (UTC) Content-Transfer-Encoding: quoted-printable 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] [PULL 25/28] block: Add bdrv_reset_options_allowed() 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" Content-Type: text/plain; charset="utf-8" From: Alberto Garcia bdrv_reopen_prepare() receives a BDRVReopenState with (among other things) a new set of options to be applied to that BlockDriverState. If an option is missing then it means that we want to reset it to its default value rather than keep the previous one. This way the state of the block device after being reopened is comparable to that of a device added with "blockdev-add" using the same set of options. Not all options from all drivers can be changed this way, however. If the user attempts to reset an immutable option to its default value using this method then we must forbid it. This new function takes a BlockDriverState and a new set of options and checks if there's any option that was previously set but is missing from the new set of options. If the option is present in both sets we don't need to check that they have the same value. The loop at the end of bdrv_reopen_prepare() already takes care of that. Signed-off-by: Alberto Garcia Signed-off-by: Kevin Wolf --- block.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/block.c b/block.c index c6786cd35b..a5e69ad81e 100644 --- a/block.c +++ b/block.c @@ -2983,6 +2983,53 @@ BlockDriverState *bdrv_open(const char *filename, co= nst char *reference, NULL, errp); } =20 +/* Return true if the NULL-terminated @list contains @str */ +static bool is_str_in_list(const char *str, const char *const *list) +{ + if (str && list) { + int i; + for (i =3D 0; list[i] !=3D NULL; i++) { + if (!strcmp(str, list[i])) { + return true; + } + } + } + return false; +} + +/* + * Check that every option set in @bs->options is also set in + * @new_opts. + * + * Options listed in the common_options list and in + * @bs->drv->mutable_opts are skipped. + * + * Return 0 on success, otherwise return -EINVAL and set @errp. + */ +static int bdrv_reset_options_allowed(BlockDriverState *bs, + const QDict *new_opts, Error **errp) +{ + const QDictEntry *e; + /* These options are common to all block drivers and are handled + * in bdrv_reopen_prepare() so they can be left out of @new_opts */ + const char *const common_options[] =3D { + "node-name", "discard", "cache.direct", "cache.no-flush", + "read-only", "auto-read-only", "detect-zeroes", NULL + }; + + for (e =3D qdict_first(bs->options); e; e =3D qdict_next(bs->options, = e)) { + if (!qdict_haskey(new_opts, e->key) && + !is_str_in_list(e->key, common_options) && + !is_str_in_list(e->key, bs->drv->mutable_opts)) { + error_setg(errp, "Option '%s' cannot be reset " + "to its default value", e->key); + return -EINVAL; + } + } + + return 0; +} + /* * Returns true if @child can be reached recursively from @bs */ @@ -3546,6 +3593,17 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_stat= e, BlockReopenQueue *queue, } =20 if (drv->bdrv_reopen_prepare) { + /* + * If a driver-specific option is missing, it means that we + * should reset it to its default value. + * But not all options allow that, so we need to check it first. + */ + ret =3D bdrv_reset_options_allowed(reopen_state->bs, + reopen_state->options, errp); + if (ret) { + goto error; + } + ret =3D drv->bdrv_reopen_prepare(reopen_state, queue, &local_err); if (ret) { if (local_err !=3D NULL) { --=20 2.20.1