From nobody Sun Oct 5 21:12:41 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 1553726522593778.1591614187719; Wed, 27 Mar 2019 15:42:02 -0700 (PDT) Received: from localhost ([127.0.0.1]:54812 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9HEu-0001sD-3g for importer@patchew.org; Wed, 27 Mar 2019 18:41:44 -0400 Received: from eggs.gnu.org ([209.51.188.92]:50627) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h9HCn-0000VH-F0 for qemu-devel@nongnu.org; Wed, 27 Mar 2019 18:39:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h9HCm-0006kf-DI for qemu-devel@nongnu.org; Wed, 27 Mar 2019 18:39:33 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36038) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h9HCj-0006jm-Rz; Wed, 27 Mar 2019 18:39:30 -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 115BE811DC; Wed, 27 Mar 2019 22:39:29 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-59.phx2.redhat.com [10.3.116.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id 66F0A5C23D; Wed, 27 Mar 2019 22:39:28 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Wed, 27 Mar 2019 17:39:21 -0500 Message-Id: <20190327223921.32601-4-eblake@redhat.com> In-Reply-To: <20190327223921.32601-1-eblake@redhat.com> References: <20190327223921.32601-1-eblake@redhat.com> MIME-Version: 1.0 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.27]); Wed, 27 Mar 2019 22:39:29 +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] [PATCH v2 3/3] nbd/server: Advertise actual minimum block size 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 , vsementsov@virtuozzo.com, jsnow@redhat.com, qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Both NBD_CMD_BLOCK_STATUS and structured NBD_CMD_READ will split their reply according to bdrv_block_status() boundaries. If the block device has a request_alignment smaller than 512, but we advertise a block alignment of 512 to the client, then this can result in the server reply violating client expectations by reporting a smaller region of the export than what the client is permitted to address (although this is less of an issue for qemu 4.0 clients, given recent client patches to overlook our non-compliance). Since it's always better to be strict in what we send, it is worth advertising the actual minimum block limit rather than blindly rounding it up to 512. Note that this patch is not foolproof - it is still possible to provoke non-compliant server behavior using: $ qemu-nbd --image-opts driver=3Dblkdebug,align=3D512,image.driver=3Dfile,i= mage.filename=3D/path/to/non-aligned-file But as blkdebug is not normally used, and as this patch makes our server more interoperable with qemu 3.1 clients, it is worth applying now, even while we still work on a larger patch for the 4.1 timeframe to improve the block layer to prevent the mid-block status changes that can be observed now with blkdebug or with a backing layer with smaller alignment than the active layer. Note that the iotests output changes - both pre- and post-patch, the server is reporting a mid-sector hole; but pre-patch, the client was then rounding that up to a sector boundary as a workaround, while post-patch the client doesn't have to round because it sees the server's smaller advertised block size. Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- nbd/server.c | 12 +++++++----- tests/qemu-iotests/241.out | 3 ++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index fd013a2817a..c76f32dbb50 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -607,13 +607,15 @@ static int nbd_negotiate_handle_info(NBDClient *clien= t, uint16_t myflags, /* Send NBD_INFO_BLOCK_SIZE always, but tweak the minimum size * according to whether the client requested it, and according to * whether this is OPT_INFO or OPT_GO. */ - /* minimum - 1 for back-compat, or 512 if client is new enough. - * TODO: consult blk_bs(blk)->bl.request_alignment? */ - sizes[0] =3D - (client->opt =3D=3D NBD_OPT_INFO || blocksize) ? BDRV_SECTOR_S= IZE : 1; + /* minimum - 1 for back-compat, or actual if client will obey it. */ + if (client->opt =3D=3D NBD_OPT_INFO || blocksize) { + sizes[0] =3D blk_get_request_alignment(exp->blk); + } else { + sizes[0] =3D 1; + } /* preferred - Hard-code to 4096 for now. * TODO: is blk_bs(blk)->bl.opt_transfer appropriate? */ - sizes[1] =3D 4096; + sizes[1] =3D MAX(4096, sizes[0]); /* maximum - At most 32M, but smaller as appropriate. */ sizes[2] =3D MIN(blk_get_max_transfer(exp->blk), NBD_MAX_BUFFER_SIZE); trace_nbd_negotiate_handle_info_block_size(sizes[0], sizes[1], sizes[2= ]); diff --git a/tests/qemu-iotests/241.out b/tests/qemu-iotests/241.out index 044afc0c6f8..a7f1e665a9a 100644 --- a/tests/qemu-iotests/241.out +++ b/tests/qemu-iotests/241.out @@ -2,6 +2,7 @@ QA output created by 241 =3D=3D=3D Exporting unaligned raw image =3D=3D=3D -[{ "start": 0, "length": 1024, "depth": 0, "zero": false, "data": true}] +[{ "start": 0, "length": 1000, "depth": 0, "zero": false, "data": true}, +{ "start": 1000, "length": 24, "depth": 0, "zero": true, "data": true}] 1 KiB (0x400) bytes allocated at offset 0 bytes (0x0) *** done --=20 2.20.1