From nobody Sun Oct 5 21:12:42 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 1547484445883512.664577562818; Mon, 14 Jan 2019 08:47:25 -0800 (PST) Received: from localhost ([127.0.0.1]:43311 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gj5OW-0003po-Pf for importer@patchew.org; Mon, 14 Jan 2019 11:47:24 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58225) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gj55V-0004nC-SP for qemu-devel@nongnu.org; Mon, 14 Jan 2019 11:27:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gj55T-00061A-TH for qemu-devel@nongnu.org; Mon, 14 Jan 2019 11:27:45 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47132) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gj55O-0005oa-PF; Mon, 14 Jan 2019 11:27:38 -0500 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 979C3CC27E; Mon, 14 Jan 2019 16:27:26 +0000 (UTC) Received: from blue.redhat.com (ovpn-117-16.phx2.redhat.com [10.3.117.16]) by smtp.corp.redhat.com (Postfix) with ESMTP id BADA05C7B2; Mon, 14 Jan 2019 16:27:25 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Mon, 14 Jan 2019 10:26:04 -0600 Message-Id: <20190114162605.5330-20-eblake@redhat.com> In-Reply-To: <20190114162605.5330-1-eblake@redhat.com> References: <20190114162605.5330-1-eblake@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.30]); Mon, 14 Jan 2019 16:27:26 +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 19/20] nbd: Merge nbd_export_bitmap into nbd_export_new 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: Kevin Wolf , Vladimir Sementsov-Ogievskiy , "open list:Block layer core" , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" We only have one caller that wants to export a bitmap name, which it does right after creation of the export. But there is still a brief window of time where an NBD client could see the export but not the dirty bitmap, which a robust client would have to interpret as meaning the entire image should be treated as dirty. Better is to eliminate the window entirely, by inlining nbd_export_bitmap() into nbd_export_new(), and refusing to create the bitmap in the first place if the requested bitmap can't be located. We also no longer need logic for setting a different bitmap name compared to the bitmap being exported. Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy Message-Id: <20190111194720.15671-8-eblake@redhat.com> --- include/block/nbd.h | 9 ++--- blockdev-nbd.c | 11 +----- nbd/server.c | 87 +++++++++++++++++++++------------------------ qemu-nbd.c | 5 +-- 4 files changed, 47 insertions(+), 65 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index 2f9a2aeb73c..1971b557896 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -296,9 +296,9 @@ typedef struct NBDClient NBDClient; NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t si= ze, const char *name, const char *description, - uint16_t nbdflags, void (*close)(NBDExport *), - bool writethrough, BlockBackend *on_eject_blk, - Error **errp); + const char *bitmap, uint16_t nbdflags, + void (*close)(NBDExport *), bool writethrough, + BlockBackend *on_eject_blk, Error **errp); void nbd_export_close(NBDExport *exp); void nbd_export_remove(NBDExport *exp, NbdServerRemoveMode mode, Error **e= rrp); void nbd_export_get(NBDExport *exp); @@ -319,9 +319,6 @@ void nbd_client_put(NBDClient *client); void nbd_server_start(SocketAddress *addr, const char *tls_creds, Error **errp); -void nbd_export_bitmap(NBDExport *exp, const char *bitmap, - const char *bitmap_export_name, Error **errp); - /* nbd_read * Reads @size bytes from @ioc. Returns 0 on success. */ diff --git a/blockdev-nbd.c b/blockdev-nbd.c index cd86b38cdaa..c76d5416b90 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -175,7 +175,7 @@ void qmp_nbd_server_add(const char *device, bool has_na= me, const char *name, writable =3D false; } - exp =3D nbd_export_new(bs, 0, -1, name, NULL, + exp =3D nbd_export_new(bs, 0, -1, name, NULL, bitmap, writable ? 0 : NBD_FLAG_READ_ONLY, NULL, false, on_eject_blk, errp); if (!exp) { @@ -186,15 +186,6 @@ void qmp_nbd_server_add(const char *device, bool has_n= ame, const char *name, * our only way of accessing it is through nbd_export_find(), so we ca= n drop * the strong reference that is @exp. */ nbd_export_put(exp); - - if (has_bitmap) { - Error *err =3D NULL; - nbd_export_bitmap(exp, bitmap, bitmap, &err); - if (err) { - error_propagate(errp, err); - nbd_export_remove(exp, NBD_SERVER_REMOVE_MODE_HARD, NULL); - } - } } void qmp_nbd_server_remove(const char *name, diff --git a/nbd/server.c b/nbd/server.c index bb5438c448b..e8c56607eff 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1457,9 +1457,9 @@ static void nbd_eject_notifier(Notifier *n, void *dat= a) NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t si= ze, const char *name, const char *description, - uint16_t nbdflags, void (*close)(NBDExport *), - bool writethrough, BlockBackend *on_eject_blk, - Error **errp) + const char *bitmap, uint16_t nbdflags, + void (*close)(NBDExport *), bool writethrough, + BlockBackend *on_eject_blk, Error **errp) { AioContext *ctx; BlockBackend *blk; @@ -1507,6 +1507,43 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_= t dev_offset, off_t size, } exp->size -=3D exp->size % BDRV_SECTOR_SIZE; + if (bitmap) { + BdrvDirtyBitmap *bm =3D NULL; + BlockDriverState *bs =3D blk_bs(blk); + + while (true) { + bm =3D bdrv_find_dirty_bitmap(bs, bitmap); + if (bm !=3D NULL || bs->backing =3D=3D NULL) { + break; + } + + bs =3D bs->backing->bs; + } + + if (bm =3D=3D NULL) { + error_setg(errp, "Bitmap '%s' is not found", bitmap); + goto fail; + } + + if ((nbdflags & NBD_FLAG_READ_ONLY) && bdrv_is_writable(bs) && + bdrv_dirty_bitmap_enabled(bm)) { + error_setg(errp, + "Enabled bitmap '%s' incompatible with readonly exp= ort", + bitmap); + goto fail; + } + + if (bdrv_dirty_bitmap_user_locked(bm)) { + error_setg(errp, "Bitmap '%s' is in use", bitmap); + goto fail; + } + + bdrv_dirty_bitmap_set_qmp_locked(bm, true); + exp->export_bitmap =3D bm; + exp->export_bitmap_context =3D g_strdup_printf("qemu:dirty-bitmap:= %s", + bitmap); + } + exp->close =3D close; exp->ctx =3D blk_get_aio_context(blk); blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, ex= p); @@ -2424,47 +2461,3 @@ void nbd_client_new(QIOChannelSocket *sioc, co =3D qemu_coroutine_create(nbd_co_client_start, client); qemu_coroutine_enter(co); } - -void nbd_export_bitmap(NBDExport *exp, const char *bitmap, - const char *bitmap_export_name, Error **errp) -{ - BdrvDirtyBitmap *bm =3D NULL; - BlockDriverState *bs =3D blk_bs(exp->blk); - - if (exp->export_bitmap) { - error_setg(errp, "Export bitmap is already set"); - return; - } - - while (true) { - bm =3D bdrv_find_dirty_bitmap(bs, bitmap); - if (bm !=3D NULL || bs->backing =3D=3D NULL) { - break; - } - - bs =3D bs->backing->bs; - } - - if (bm =3D=3D NULL) { - error_setg(errp, "Bitmap '%s' is not found", bitmap); - return; - } - - if ((exp->nbdflags & NBD_FLAG_READ_ONLY) && bdrv_is_writable(bs) && - bdrv_dirty_bitmap_enabled(bm)) { - error_setg(errp, - "Enabled bitmap '%s' incompatible with readonly export", - bitmap); - return; - } - - if (bdrv_dirty_bitmap_user_locked(bm)) { - error_setg(errp, "Bitmap '%s' is in use", bitmap); - return; - } - - bdrv_dirty_bitmap_set_qmp_locked(bm, true); - exp->export_bitmap =3D bm; - exp->export_bitmap_context =3D - g_strdup_printf("qemu:dirty-bitmap:%s", bitmap_export_name); -} diff --git a/qemu-nbd.c b/qemu-nbd.c index b93fa196dac..1552274c189 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -1016,8 +1016,9 @@ int main(int argc, char **argv) } export =3D nbd_export_new(bs, dev_offset, fd_size, export_name, - export_description, nbdflags, nbd_export_close= d, - writethrough, NULL, &error_fatal); + export_description, NULL, nbdflags, + nbd_export_closed, writethrough, NULL, + &error_fatal); if (device) { #if HAVE_NBD_DEVICE --=20 2.20.1