From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1787691527; cv=none; d=zohomail.com; s=zohoarc; b=WCPrEATp/HjZGfGvQpqI/HLQ1g1kxqfuO65dVvX6dSNK4mkIivRLwLBxmu0aBdMVoM7HDjU9KDHx6HzatkpwwwXbIF4SHGnNmKIRRcpWtv1ddhTABqKgUIeed9m8Ur2awD8VjN5vLHtfLmS4FJ8AJb1HkRLsQggfAYCtgpqmYqs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787691527; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=4qCZ5806sp3O28Ci7LEsz346P1orFWcCswMIuQ/hzc8=; b=grkhn86hrGf38ZerW7iqn3C8hBmDvqmFnSkIKVs+8CnPOC9jaSbfcQ11SxJuJP4jI1/wkHTFCPC5NtB4iJYI2X01AYM8yx6pHjSkFQqMtOvFPU5gJpaweejq7ztUWpOdWRTGLCK+klAr8fhVRPE6EpigfakljsmCgMPesBZFcOU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787691527309182.7877559764629; Tue, 25 Aug 2026 13:58:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyyDd-000154-NE; Tue, 25 Aug 2026 16:58:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDc-000149-6R; Tue, 25 Aug 2026 16:58:04 -0400 Received: from tor.source.kernel.org ([2600:3c04:e001:324:0:1991:8:25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDa-000379-Lo; Tue, 25 Aug 2026 16:58:03 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by tor.source.kernel.org (Postfix) with ESMTP id C155760053; Tue, 25 Aug 2026 20:58:00 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B53DF1F000E9; Tue, 25 Aug 2026 20:57:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787691480; bh=4qCZ5806sp3O28Ci7LEsz346P1orFWcCswMIuQ/hzc8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Yi0K3Tg4/36wLr5XwAJWGfB58OaMrJ5YUZ2U0UOrSroMCIhjizwfDVbkiKwG3o5NP iFdYxJ5SV6HfUNeJHBIewOUhueTRWu8RSQK60yFizVSZnDPINk5HVCTHNtAIkQ9nyd 7DQy+HX04jSi4YmquCTGDpOZcXUqZEhPX2NLtWumcA184VRss4LFCd3L3N8mY+a71T d0C9hKsY6MGCIyRbPZpZSFDRPufPbrDtfBHA3T9ei0IB+ULMcTz/QXcf5/qXKTdtgA zhDqUikhaoaS22lwIacHd7CO8e6BCHJIlMh5alFiRk2e2udOlMU29Kl8jJYK0hzIk3 0Wk9Gyz6lnmRA== From: Niklas Cassel To: Stefan Hajnoczi , Kevin Wolf , Hanna Reitz Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 01/12] block: widen BlockLimits.zone_size to uint64_t Date: Tue, 25 Aug 2026 22:57:36 +0200 Message-ID: <20260825205748.679968-2-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825205748.679968-1-cassel@kernel.org> References: <20260825205748.679968-1-cassel@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=lists1p.gnu.org; Received-SPF: pass client-ip=2600:3c04:e001:324:0:1991:8:25; envelope-from=cassel@kernel.org; helo=tor.source.kernel.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1787691529694158500 Content-Type: text/plain; charset="utf-8" From: Sam Li The zone-size field in BlockLimits is currently uint32_t, capping expressible zone sizes at 4 GiB. Real zoned-device protocols like NVMe ZNS allow larger zones. Widen BlockLimits.zone_size to uint64_t to match. Signed-off-by: Sam Li Reviewed-by: Niklas Cassel Signed-off-by: Niklas Cassel Reviewed-by: Damien Le Moal --- block/file-posix.c | 2 +- include/block/block_int-common.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/block/file-posix.c b/block/file-posix.c index 01037f4b5c..dd9e3d4c37 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -3598,7 +3598,7 @@ raw_co_zone_append(BlockDriverState *bs, =20 if (*offset & zone_size_mask) { error_report("sector offset %" PRId64 " is not aligned to zone siz= e " - "%" PRId32 "", *offset / 512, bs->bl.zone_size / 512); + "%" PRId64 "", *offset / 512, bs->bl.zone_size / 512); return -EINVAL; } =20 diff --git a/include/block/block_int-common.h b/include/block/block_int-com= mon.h index 147c08155f..7571ed9968 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -901,7 +901,7 @@ typedef struct BlockLimits { BlockZoneModel zoned; =20 /* zone size expressed in bytes */ - uint32_t zone_size; + uint64_t zone_size; =20 /* total number of zones */ uint32_t nr_zones; --=20 2.55.0 From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1787691567; cv=none; d=zohomail.com; s=zohoarc; b=Lu6VusPUJhydGJxNxDZ+Olvbg++KdfJrm9T7LY4Jtmnu0UT7Y06pe0tcZaV2sMBkB6v2BS5fc8jp12r9mGI8lwhpe2v8Et5Pg+tZI9fxz4/uLzItTAgWccQOwnCDi0TnnL+0IpnE5PEGXe5os7/oKDJBzR1wtSmfN/Lf33izpiA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787691567; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=7Ss2ZVSrV3pYAUsWq9whlhRExAzEBkJ1xfNAMgLXaA4=; b=cvRzu57yacdQ2XujEzwJ12/tyaCQs2VsR8DUsVEfa41sg5T7Di9yK3KcTWVJADw+WbjtjDLCIi6pnN1L+cGj507jqHLkkmUWfW8Bm8tHjh1nAo6zAOaUyKj/P02D9r3WqpaZmdj9m7QCZbJqR+eSZ9VbhLpoJoWSXwiE1wpTxzA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787691567337783.7946251704392; Tue, 25 Aug 2026 13:59:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyyDg-00016N-BV; Tue, 25 Aug 2026 16:58:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDe-00015T-7u; Tue, 25 Aug 2026 16:58:06 -0400 Received: from sea.source.kernel.org ([172.234.252.31]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDc-00037l-GJ; Tue, 25 Aug 2026 16:58:05 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 2484E41991; Tue, 25 Aug 2026 20:58:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 08B051F000E9; Tue, 25 Aug 2026 20:58:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787691483; bh=7Ss2ZVSrV3pYAUsWq9whlhRExAzEBkJ1xfNAMgLXaA4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=VNw1DGJtaX3gorve+CnpciHwKfZvgIE0U0cknhOlTCAMpPINV+ON1c5ZFkLzCir6a gmeUxr2IpVLYSC4qtf9eWRPKY3INcs5MeEYeHkA9B4pDfo/W/pjtP4JRYbI8POhK+Y 9HmgMrFiWYRJ4XY7tfq35SOYhgz4TCrX2nN2cI68X+uG7gZ1EPuUzmjS2a0qvpqi87 PBqzXMSrR5cQi7KlgbtKDow7RZQXe//sv50aFWIr+MfLefOasZPLcZshd7cxl9j0EX kd+ylV0E5Z8u/otzB5YrLKJ13Wxk4dmHh4G/M12uSRMNxRmHf2qHFyWIlWO50EaDWn KZsWXBSq2fLnQ== From: Niklas Cassel To: Stefan Hajnoczi , Kevin Wolf , Hanna Reitz , "Michael S. Tsirkin" Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 02/12] virtio-blk: do not merge writes across a zone boundary Date: Tue, 25 Aug 2026 22:57:37 +0200 Message-ID: <20260825205748.679968-3-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825205748.679968-1-cassel@kernel.org> References: <20260825205748.679968-1-cassel@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=lists1p.gnu.org; Received-SPF: pass client-ip=172.234.252.31; envelope-from=cassel@kernel.org; helo=sea.source.kernel.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1787691569098158500 Content-Type: text/plain; charset="utf-8" From: Sam Li virtio_blk_submit_multireq() fuses adjacent in-zone requests into a single request. On a zoned backend, a merged zone append request that straddles a zone boundary is rejected by the device because each write must stay within a single zone. Add a bail condition to the merge coalescer: if combining the candidate request into the current batch would cross a zone boundary, flush the current batch and start a new one. Signed-off-by: Sam Li Reviewed-by: Stefan Hajnoczi Reviewed-by: Niklas Cassel Signed-off-by: Niklas Cassel Reviewed-by: Damien Le Moal --- block/block-backend.c | 11 +++++++++++ hw/block/virtio-blk.c | 22 +++++++++++++++++++++- include/system/block-backend-io.h | 1 + 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/block/block-backend.c b/block/block-backend.c index 37ba7e9fc4..049e70ddcb 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -2326,6 +2326,17 @@ uint32_t blk_get_request_alignment(BlockBackend *blk) return bs ? bs->bl.request_alignment : BDRV_SECTOR_SIZE; } =20 +/* + * Returns the zone size in bytes for a zoned backend, or 0 if @blk does + * not present zoned geometry. + */ +uint64_t blk_get_zone_size(BlockBackend *blk) +{ + BlockDriverState *bs =3D blk_bs(blk); + IO_CODE(); + return bs ? bs->bl.zone_size : 0; +} + /* Returns the optimal write zeroes alignment, in bytes; guaranteed nonzer= o */ uint32_t blk_get_pwrite_zeroes_alignment(BlockBackend *blk) { diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 6b92066aff..f74cc3dbd0 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -294,6 +294,9 @@ static void virtio_blk_submit_multireq(VirtIOBlock *s, = MultiReqBuffer *mrb) int i =3D 0, start =3D 0, num_reqs =3D 0, niov =3D 0, nb_sectors =3D 0; uint32_t max_transfer; int64_t sector_num =3D 0; + uint64_t zone_size =3D blk_get_zone_size(s->blk); + bool zone_cross; + int64_t zone_sector, end_sector; =20 if (mrb->num_reqs =3D=3D 1) { submit_requests(s, mrb, 0, 1, -1); @@ -309,17 +312,34 @@ static void virtio_blk_submit_multireq(VirtIOBlock *s= , MultiReqBuffer *mrb) for (i =3D 0; i < mrb->num_reqs; i++) { VirtIOBlockReq *req =3D mrb->reqs[i]; if (num_reqs > 0) { + zone_cross =3D false; + + /* + * On zoned backends, a single backend write/read must not span + * a zone boundary. Bail out of merging if combining req into + * the current batch would straddle a zone. + */ + if (zone_size > 0) { + zone_sector =3D zone_size / BDRV_SECTOR_SIZE; + end_sector =3D req->sector_num + + req->qiov.size / BDRV_SECTOR_SIZE - 1; + zone_cross =3D (sector_num / zone_sector) !=3D + (end_sector / zone_sector); + } + /* * NOTE: We cannot merge the requests in below situations: * 1. requests are not sequential * 2. merge would exceed maximum number of IOVs * 3. merge would exceed maximum transfer length of backend de= vice + * 4. merge would cross a zone boundary on a zoned backend */ if (sector_num + nb_sectors !=3D req->sector_num || niov > blk_get_max_iov(s->blk) - req->qiov.niov || req->qiov.size > max_transfer || nb_sectors > (max_transfer - - req->qiov.size) / BDRV_SECTOR_SIZE) { + req->qiov.size) / BDRV_SECTOR_SIZE || + zone_cross) { submit_requests(s, mrb, start, num_reqs, niov); num_reqs =3D 0; } diff --git a/include/system/block-backend-io.h b/include/system/block-backe= nd-io.h index fd84723d9d..78d410b8df 100644 --- a/include/system/block-backend-io.h +++ b/include/system/block-backend-io.h @@ -121,6 +121,7 @@ uint32_t blk_get_request_alignment(BlockBackend *blk); uint32_t blk_get_pwrite_zeroes_alignment(BlockBackend *blk); uint32_t blk_get_max_transfer(BlockBackend *blk); uint64_t blk_get_max_hw_transfer(BlockBackend *blk); +uint64_t blk_get_zone_size(BlockBackend *blk); =20 int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in, BlockBackend *blk_out, int64_t off_out, --=20 2.55.0 From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1787691528; cv=none; d=zohomail.com; s=zohoarc; b=F4qpfTvBsSh2LTXwAEosCrYcspc5yzAqx8nZDqhM6+lTKys9cqIZQYMymlBoUgfZI5zeOMebmxmQ+3n6C4qFSdfvA0y9RHVX+C1mluimGNRyWLhJceCrcFsrbtkXjZSTmVbKDdODjdN3oNqnGBfapCBXqfMPIauOkD+dVSRPrN4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787691528; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=L793T09DHu/KWT0lp5U50ovDLcAH53XzTINX6JLT98k=; b=gKQ3azZh9lY/XNEzzJQF23Tv2OZ4F2DV6dXojDOahLVOQ9oDJWrhAV5L5BkRqacdnx4ansfe5fx4KNzW/hrXNAp7maSVeBzBlUcrUm1UBIo/gDWyOXSj6L3Nys6aIqVdrBCR+E5lG7Hy3nitD6SS59J19bIOZc6LawEdKbDAyfI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787691528353718.2468467530925; Tue, 25 Aug 2026 13:58:48 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyyDn-00018t-Pa; Tue, 25 Aug 2026 16:58:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDg-00016T-FT; Tue, 25 Aug 2026 16:58:08 -0400 Received: from sea.source.kernel.org ([2600:3c0a:e001:78e:0:1991:8:25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDe-0003A3-SA; Tue, 25 Aug 2026 16:58:08 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 636B841996; Tue, 25 Aug 2026 20:58:05 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8615F1F000E9; Tue, 25 Aug 2026 20:58:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787691485; bh=L793T09DHu/KWT0lp5U50ovDLcAH53XzTINX6JLT98k=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=HYY+R/8lAIHZl3H7IS2tciWh8TgiWf5KB9QiT61hH1VmYWLgVcdjmso4gdkQ+EuEY yjADd7TYyxGJc8AFd18DXXNk/gO9a08xzbVXkWL+e353iwp5mrpyUKP4/Oop8Dkzw3 srniLUhn69/1xmrPL1tc5RAoHg7LrX+nmEkq008qX68G5NmZkjeCLIzqDJteCe2PFi vA7dNTU0UiZuCgXwtw2zQD3l1ZHTyQqI7cJnZk7JpPW76APQJaQaAUskopc2oj6KIC EhRbUjGRQDL0/9VAQXuvbRsxrXoPPb/EKR70fwXidDzWmxoGQPoh59yPK9UX1REAdK tp29SC6vohCKw== From: Niklas Cassel To: Stefan Hajnoczi , Kevin Wolf , Hanna Reitz Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 03/12] file-posix: fix zone write granularity assignment for zoned block devices Date: Tue, 25 Aug 2026 22:57:38 +0200 Message-ID: <20260825205748.679968-4-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825205748.679968-1-cassel@kernel.org> References: <20260825205748.679968-1-cassel@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=lists1p.gnu.org; Received-SPF: pass client-ip=2600:3c0a:e001:78e:0:1991:8:25; envelope-from=cassel@kernel.org; helo=sea.source.kernel.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1787691530882158500 Content-Type: text/plain; charset="utf-8" In the ZBC and ZAC specifications, the requirement is that the write granularity matches the physical block size. However, in the ZNS specification, the requirement is simply that the write granularity matches the logical block size. See: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?= id=3Da805a4fa4fa376bbc145762bb8b09caa2fa8af48 In Linux, there is a zone_write_granularity sysfs property which abstracts this away, so let's make use of it. Currently, it is theoretically possible that QEMU presents an inflated write granularity for NVMe devices where the physical block size is larger than the logical block size. Reviewed-by: Damien Le Moal Reviewed-by: Stefan Hajnoczi Fixes: a3c41f06d5a8 ("file-posix: add tracking of the zone write pointers") Signed-off-by: Niklas Cassel --- block/file-posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/file-posix.c b/block/file-posix.c index dd9e3d4c37..c0d6ee30e4 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -1493,7 +1493,7 @@ static void raw_refresh_zoned_limits(BlockDriverState= *bs, struct stat *st, bs->bl.max_append_sectors =3D ret >> BDRV_SECTOR_BITS; } =20 - ret =3D get_sysfs_long_val(st, "physical_block_size"); + ret =3D get_sysfs_long_val(st, "zone_write_granularity"); if (ret >=3D 0) { bs->bl.write_granularity =3D ret; } --=20 2.55.0 From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1787691536; cv=none; d=zohomail.com; s=zohoarc; b=Keo7ZaU+682dc4faW1BbQYhYJXnD6HYZ0wRPJQiP8jKs8DZvjQZPDbTTA1a6KE4wjfEagzbyKnUFlpx4aDDaKIaf5Agx80Jtzv68a5tnDZ+UuCHPmrzfump16XnThLWH+cce0Q10rvStugFY7pomFAIFr0mAzjy5wDp5nE83rss= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787691536; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=T/FQc2S9cUUnnAKDIVcw5oObxzP0pss00sEQ+BeGaBU=; b=SZEEU1Hb8moZew/PfwMgHkFCpw3ZUIq/o97dgH6qla9mkSsZ5bjzthm3SzUQoUmZUZrP207576aWvbtkUeoBgTN1+KpuDtAsqygCDoe7LGaXGrmsQG6QE3XdWRll7RHt2/s22H265t0ldv03Asf0OnuSCLTwegBwkgfWxCK3p8U= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787691536132742.9874549550528; Tue, 25 Aug 2026 13:58:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyyDr-0001AM-Qp; Tue, 25 Aug 2026 16:58:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDn-00018s-Lr; Tue, 25 Aug 2026 16:58:15 -0400 Received: from sea.source.kernel.org ([2600:3c0a:e001:78e:0:1991:8:25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDh-0003D8-HR; Tue, 25 Aug 2026 16:58:14 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 37AB340776; Tue, 25 Aug 2026 20:58:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CC4761F000E9; Tue, 25 Aug 2026 20:58:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787691488; bh=T/FQc2S9cUUnnAKDIVcw5oObxzP0pss00sEQ+BeGaBU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=KSFDkJLOZ4weq2sT657DD3ZNko2lmNs/6N+lC1718PG/Ys/l9j7kRikoanVptYPkL 1gV9Ue08KujNLiqrgWZrPW98txW2DnLvicujQCCDbVPNrzGKw7DjMkqWH9okZKPwgU NaU5I5DQSmjTTbdR6Vk2yHVInglWaXymTE7aCiEEgTvfQjEicByQ2YHEiUTiY/TOgo vnBUT3/zEHkDi00kObW4V5K0y4o2J6EumV5nDnm5yiIjshYKWWLN3Hy+O2dqyeji4i h9obwT7iWpnosB9ePUBrBgTQuzOwkHhL5NGH39QRHXdoiFZO8lQJxRqlxAI0h6x+2D /heZ86lVYTQWQ== From: Niklas Cassel To: Stefan Hajnoczi , John Snow , "Denis V. Lunev" , Kevin Wolf , Hanna Reitz , "Michael S. Tsirkin" Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 04/12] virtio-blk: report the effective zone write granularity Date: Tue, 25 Aug 2026 22:57:39 +0200 Message-ID: <20260825205748.679968-5-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825205748.679968-1-cassel@kernel.org> References: <20260825205748.679968-1-cassel@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=lists1p.gnu.org; Received-SPF: pass client-ip=2600:3c0a:e001:78e:0:1991:8:25; envelope-from=cassel@kernel.org; helo=sea.source.kernel.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1787691537188158500 Content-Type: text/plain; charset="utf-8" For ZBC/ZAC devices the write granularity is the physical block size, so a 512e SMR disk exposed through a host_device backend has a logical block size of 512 and a zone write granularity of 4096. We told the guest driver = 512 while raw_co_zone_append() rejects anything that is not 4096 byte aligned, so the driver saw a plain I/O error for a request it had been told was valid. Report the larger of the backend granularity and the logical block size instead. The guest driver cannot issue writes finer than the logical size, so the larger of the two is the constraint that applies. This matches what a Linux guest derives for itself: blk_validate_zoned_limits() raises zone_write_granularity to the logical block size, and blk_stack_limits() stacks it with max(). Add it as a helper next to blkconf_blocksizes(), since it is derived from a BlockConf and the limits of the backend below it, and use it for the zone append offset check in check_zoned_request(), which validated against bs->bl.write_granularity. The value reported to the driver and the value that requests are validated against then cannot drift apart. The helper cannot return zero because blkconf_blocksizes() always leaves a logical block size behind, so the check no longer needs to guard against an unset granularity. Fixes: 4f7366506a96 ("virtio-blk: add zoned storage emulation for zoned dev= ices") Signed-off-by: Niklas Cassel Reviewed-by: Damien Le Moal --- hw/block/block.c | 7 +++++++ hw/block/virtio-blk.c | 13 +++++++------ include/hw/block/block.h | 8 ++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/hw/block/block.c b/hw/block/block.c index f187fa025d..1c3135843d 100644 --- a/hw/block/block.c +++ b/hw/block/block.c @@ -201,6 +201,13 @@ bool blkconf_blocksizes(BlockConf *conf, Error **errp) return true; } =20 +uint32_t blkconf_zone_write_granularity(BlockConf *conf) +{ + BlockDriverState *bs =3D blk_bs(conf->blk); + + return MAX(bs->bl.write_granularity, conf->logical_block_size); +} + bool blkconf_apply_backend_options(BlockConf *conf, bool readonly, bool resizable, Error **errp) { diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index f74cc3dbd0..f8cda1baa7 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -520,11 +520,11 @@ static bool check_zoned_request(VirtIOBlock *s, int64= _t offset, int64_t len, } =20 if (append) { - if (bs->bl.write_granularity) { - if ((offset % bs->bl.write_granularity) !=3D 0) { - *status =3D VIRTIO_BLK_S_ZONE_UNALIGNED_WP; - return false; - } + uint32_t wg_mask =3D blkconf_zone_write_granularity(&s->conf.conf)= - 1; + + if (offset & wg_mask) { + *status =3D VIRTIO_BLK_S_ZONE_UNALIGNED_WP; + return false; } =20 index =3D offset / bs->bl.zone_size; @@ -1274,7 +1274,8 @@ static void virtio_blk_update_config(VirtIODevice *vd= ev, uint8_t *config) bs->bl.max_active_zones); virtio_stl_p(vdev, &blkcfg.zoned.max_open_zones, bs->bl.max_open_zones); - virtio_stl_p(vdev, &blkcfg.zoned.write_granularity, blk_size); + virtio_stl_p(vdev, &blkcfg.zoned.write_granularity, + blkconf_zone_write_granularity(conf)); virtio_stl_p(vdev, &blkcfg.zoned.max_append_sectors, bs->bl.max_append_sectors); } else { diff --git a/include/hw/block/block.h b/include/hw/block/block.h index df941df19f..f98525c01a 100644 --- a/include/hw/block/block.h +++ b/include/hw/block/block.h @@ -114,6 +114,14 @@ bool blkconf_geometry(BlockConf *conf, int *trans, unsigned cyls_max, unsigned heads_max, unsigned secs= _max, Error **errp); bool blkconf_blocksizes(BlockConf *conf, Error **errp); +/* + * The alignment constraint that applies to writes to a sequential zone. T= he + * medium may require a coarser granularity than the logical block size, w= hile + * a guest cannot issue writes finer than the logical block size, so the + * constraint that applies is the larger of the two. A frontend must repor= t this + * value to its guest and validate requests against it. + */ +uint32_t blkconf_zone_write_granularity(BlockConf *conf); bool blkconf_apply_backend_options(BlockConf *conf, bool readonly, bool resizable, Error **errp); =20 --=20 2.55.0 From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1787691585; cv=none; d=zohomail.com; s=zohoarc; b=RxA6PMQmbKmrIho/QqqsdIMF8gUk9AnkZwnr7PJ3gzNgW6MlTFEACEDf2IyL8AKxHx33tCosTHlWsVs1n69Y0z2N1fypGFzRBUpe/3sozfjltDyT9VHPi8/8ZZVrA6TaOb/z+VMsz7lARemUs266Wi9edgFS8A3nieZ+XYzh60A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787691585; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=kyDnXcRIvbvgWddM5UPAmFcXBgLEVAb4H2IEpb22gDE=; b=DOVBQNZHYt7I/PQuvzxLnzm+ERAwnkjT5nDyqUr/sm0p+LBbTGLnLLYU2OR451dxqn1slKc8AqWNc77sCuj1cNcGWjz4oJoQVdYESOU/hJX5vtzEljfMiDlxKFvwpjXvEC4hoDEkR6nt5j0rei+cKq/T0RT3WBkIiCx5TAmGTc4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787691585581221.75473290449338; Tue, 25 Aug 2026 13:59:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyyDt-0001BK-Fx; Tue, 25 Aug 2026 16:58:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDp-00019X-19; Tue, 25 Aug 2026 16:58:17 -0400 Received: from sea.source.kernel.org ([2600:3c0a:e001:78e:0:1991:8:25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDl-0003DO-Lm; Tue, 25 Aug 2026 16:58:16 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id A26BB41998; Tue, 25 Aug 2026 20:58:10 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 999AD1F000E9; Tue, 25 Aug 2026 20:58:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787691490; bh=kyDnXcRIvbvgWddM5UPAmFcXBgLEVAb4H2IEpb22gDE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=fUDstn6UDGNxeW3xpslXABi5upFOVzIoJl+uShPW2YXBzBfXTL6Y06amvVp2PFDk6 Jcq04s6Ysr7VJGnAfLyEWQr+Is9+XfeJU6ElmbwaBLkW9cb8hgGreE3dZ349QIbJg7 Tum1Lm8s/qTbj0qSmlufobCltJiZacWIV2rlM8vtSYQ4kkvVcWSzRm5ptFD0kTsegY hCFEZ8yrdD/KxPat61548oWI/fL7N2sSeBjkBreyYEMh2rkK3H89ygrav8V7bsWVlJ +ov6KfEd4hmIuRB/oDC394fUTpZMfEZhdoLHng69ucmwn7pCQwgdxngQTOw3pYcSk1 CbvJDXZU0CS1w== From: Niklas Cassel To: Stefan Hajnoczi , "Michael S. Tsirkin" , Kevin Wolf , Hanna Reitz Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 05/12] virtio-blk: check the write granularity of writes to sequential zones Date: Tue, 25 Aug 2026 22:57:40 +0200 Message-ID: <20260825205748.679968-6-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825205748.679968-1-cassel@kernel.org> References: <20260825205748.679968-1-cassel@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=lists1p.gnu.org; Received-SPF: pass client-ip=2600:3c0a:e001:78e:0:1991:8:25; envelope-from=cassel@kernel.org; helo=sea.source.kernel.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1787691587027158500 Content-Type: text/plain; charset="utf-8" All VIRTIO_BLK_T_OUT requests issued to sequential zones and all VIRTIO_BLK_T_ZONE_APPEND requests must have an offset and a data size that are multiples of the write granularity reported by the device (virtio 1.4, 5.2.6.1), and a violation is reported as VIRTIO_BLK_S_ZONE_UNALIGNED_WP (virtio 1.4, 5.2.6). Neither request type was fully checked. Zone appends validated only the offset, while writes were not checked at all. Check the size of the appended data, and both the offset and the size of a write, against blkconf_zone_write_granularity(), so that every request the device accepts is one that the guest driver was told is valid. Writes to conventional zones keep no alignment constraint beyond the logical block size. The write path performs the check after virtio_blk_sect_range_ok() so that the zone index derived from the guest supplied sector is known to be in range. Signed-off-by: Niklas Cassel --- hw/block/virtio-blk.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index f8cda1baa7..7977f4abe5 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -522,7 +522,7 @@ static bool check_zoned_request(VirtIOBlock *s, int64_t= offset, int64_t len, if (append) { uint32_t wg_mask =3D blkconf_zone_write_granularity(&s->conf.conf)= - 1; =20 - if (offset & wg_mask) { + if (offset & wg_mask || len & wg_mask) { *status =3D VIRTIO_BLK_S_ZONE_UNALIGNED_WP; return false; } @@ -911,6 +911,29 @@ static int virtio_blk_handle_request(VirtIOBlockReq *r= eq, MultiReqBuffer *mrb) return 0; } =20 + if (is_write) { + BlockDriverState *bs =3D blk_bs(s->blk); + int64_t offset =3D req->sector_num << BDRV_SECTOR_BITS; + uint32_t wg_mask =3D + blkconf_zone_write_granularity(&s->conf.conf) - 1; + + /* + * Both the offset and the size of a write to a sequential zone + * must be a multiple of the write granularity reported by the + * device. Conventional zones are not constrained. The zone in= dex + * is derived from a guest supplied sector, so this must come = after + * virtio_blk_sect_range_ok() has bounded it. + */ + if (bs->bl.zoned !=3D BLK_Z_NONE && + (offset & wg_mask || req->qiov.size & wg_mask) && + !BDRV_ZT_IS_CONV(bs->wps->wp[offset / bs->bl.zone_size])) { + virtio_blk_req_complete(req, VIRTIO_BLK_S_ZONE_UNALIGNED_W= P); + block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_WRITE= ); + g_free(req); + return 0; + } + } + block_acct_start(blk_get_stats(s->blk), &req->acct, req->qiov.size, is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ); =20 --=20 2.55.0 From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1787691537; cv=none; d=zohomail.com; s=zohoarc; b=GsXNC06DZPg3hmTrTuodjepUzAIUABi/6onAxAUcy5sOlQ673CWTmiodDrRWYiJszDwptlViO0OgVR4AqacQhIMRGMKqPD9/TpEGVToM5CwhyeAkX55StUZPYjgzaTyq2WU+bFMXUMRyvFI1cOmS6IJub+UMraQfRLolruRXWvQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787691537; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ZVathE3hfTpCMQYovwXt7Y7kInO6xgljH8saDvtWXXs=; b=hmSel3wWHLJwrtppJTeiYSzjBuSi5mCPP9VtkZy4xyrB87KHHTvyUxXDpw9+APkEDqZDs+Q9hTKcPxATEa8SYtw95ZdSB0iEFCEtYxgSCmCfUiN656w4qgu8sJIO3OrZNtfGuvWRV77t5IaNXlq0PBz6RJHrgRrSniS1O2bvLFk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787691537527412.31188216284966; Tue, 25 Aug 2026 13:58:57 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyyDw-0001DE-Gz; Tue, 25 Aug 2026 16:58:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDq-00019l-7T; Tue, 25 Aug 2026 16:58:18 -0400 Received: from tor.source.kernel.org ([2600:3c04:e001:324:0:1991:8:25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDn-0003Dn-E0; Tue, 25 Aug 2026 16:58:16 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by tor.source.kernel.org (Postfix) with ESMTP id A58FE60053; Tue, 25 Aug 2026 20:58:13 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 17D331F000E9; Tue, 25 Aug 2026 20:58:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787691493; bh=ZVathE3hfTpCMQYovwXt7Y7kInO6xgljH8saDvtWXXs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=WUGV3PaswZZQBf+qeQ6rOSgNTSBWQPgwS09PTmXnLzYfaqaM3m9e4UK6+frFCFp+c AUnaY/k3EiU0HUVRzPoChyIg7Jq2/r15FrLgLA7WQBtFEzKldfG8GcJi5JDxoAu4bE GFmgL48xklca1SyJdFZRyjyqLbQWWOBUP4ZZ1eaduqq7UUQw45UHdQU5nftygj8T6m AWNgY4Vp0sV3Tu6ttcPq6GaJalCGc31aDi/m179q8qiDrfz0cSD260krSf5j8v7s1+ nKRplcLE+1uo76DHPSFKSukpCnkSZk7pko6sFg+9vIh4TyvOLcnG3RS9H5rTOSEaRj L1Ai0RXkfetZA== From: Niklas Cassel To: Stefan Hajnoczi , John Snow , "Denis V. Lunev" , Kevin Wolf , Hanna Reitz , "Michael S. Tsirkin" Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 06/12] hw/block: reject a zoned device whose write pointers are unaddressable Date: Tue, 25 Aug 2026 22:57:41 +0200 Message-ID: <20260825205748.679968-7-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825205748.679968-1-cassel@kernel.org> References: <20260825205748.679968-1-cassel@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=lists1p.gnu.org; Received-SPF: pass client-ip=2600:3c04:e001:324:0:1991:8:25; envelope-from=cassel@kernel.org; helo=tor.source.kernel.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1787691539045158500 Content-Type: text/plain; charset="utf-8" The write pointers of a zoned device outlive any particular use of it, whether the device keeps them itself or a backend records them, while the logical block size is a property of the frontend and is chosen afresh every time the device is attached. Nothing ties the two together. A zone written while the device was configured with logical_block_size=3D512 leaves a write pointer that is a multiple of 512, and attaching the same device with logical_block_size=3D4096 makes that pointer unaddressable. Such a pointer is not merely misaligned. The guest addresses the device in logical blocks, and a zone report expresses the write pointer in 512 byte sectors, so the guest is told about a position that does not fall on a logical block boundary. It can neither read nor write there, and the zone can only be recovered by resetting it. The reverse direction is harmless: a pointer laid down with a larger logical block size is still a multiple of a smaller one. On a zoned null_blk device with a logical block size of 512, a 512 byte append to a sequential zone leaves the write pointer half a logical block into it: $ qemu-io --image-opts -n driver=3Dhost_device,filename=3D/dev/nullb0 \ -c "zap -p 0x20000000 0x200" -c "zrp 0x20000000 1" start: 0x100000, len 0x80000, cap 0x80000, wptr 0x100001, zcond:2 Attaching that disk with logical_block_size=3D4096 handed the guest a zone it could not write to. Check at realize time that the zone size and every write pointer of a sequential zone are multiples of the write granularity that the device is about to report, and refuse to start otherwise. The write pointers are already held in memory by the driver, so this costs no I/O. The check uses blkconf_zone_write_granularity(), the same value that a frontend reports to its guest and validates requests against, so the three cannot disagree. Signed-off-by: Niklas Cassel --- hw/block/block.c | 46 ++++++++++++++++++++++++++++++++++++++++ hw/block/virtio-blk.c | 4 ++++ include/hw/block/block.h | 1 + 3 files changed, 51 insertions(+) diff --git a/hw/block/block.c b/hw/block/block.c index 1c3135843d..b908e0ef64 100644 --- a/hw/block/block.c +++ b/hw/block/block.c @@ -208,6 +208,52 @@ uint32_t blkconf_zone_write_granularity(BlockConf *con= f) return MAX(bs->bl.write_granularity, conf->logical_block_size); } =20 +bool blkconf_zoned(BlockConf *conf, Error **errp) +{ + BlockDriverState *bs =3D blk_bs(conf->blk); + uint32_t wg; + + if (bs->bl.zoned =3D=3D BLK_Z_NONE) { + return true; + } + + wg =3D blkconf_zone_write_granularity(conf); + + if (!QEMU_IS_ALIGNED(bs->bl.zone_size, wg)) { + error_setg(errp, "zone size %" PRIu64 " is not a multiple of the z= one " + "write granularity %" PRIu32, bs->bl.zone_size, wg); + return false; + } + + /* + * A write pointer that is not a multiple of the write granularity doe= s not + * fall on a logical block boundary, so the guest can neither read nor= write + * at it and the zone can only be recovered by resetting it. A backend= that + * records its write pointers, rather than reading them back from a de= vice, + * can hand us such a pointer when the zones were written while the de= vice + * was configured with a smaller logical block size. + */ + for (uint32_t i =3D 0; i < bs->bl.nr_zones; i++) { + uint64_t wp =3D bs->wps->wp[i]; + + if (BDRV_ZT_IS_CONV(wp)) { + continue; + } + + if (!QEMU_IS_ALIGNED(wp, wg)) { + error_setg(errp, "write pointer 0x%" PRIx64 " of zone %" PRIu32 + " is not a multiple of the zone write granularity %" + PRIu32, wp, i, wg); + error_append_hint(errp, "The zones were written with a smaller= " + "logical_block_size. Reset them, or keep usi= ng " + "the smaller size.\n"); + return false; + } + } + + return true; +} + bool blkconf_apply_backend_options(BlockConf *conf, bool readonly, bool resizable, Error **errp) { diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 7977f4abe5..61f7b3cdc1 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -1821,6 +1821,10 @@ static void virtio_blk_device_realize(DeviceState *d= ev, Error **errp) return; } =20 + if (!blkconf_zoned(&conf->conf, errp)) { + return; + } + bs =3D blk_bs(conf->conf.blk); if (bs->bl.zoned !=3D BLK_Z_NONE) { virtio_add_feature(&s->host_features, VIRTIO_BLK_F_ZONED); diff --git a/include/hw/block/block.h b/include/hw/block/block.h index f98525c01a..3c96de3222 100644 --- a/include/hw/block/block.h +++ b/include/hw/block/block.h @@ -122,6 +122,7 @@ bool blkconf_blocksizes(BlockConf *conf, Error **errp); * value to its guest and validate requests against it. */ uint32_t blkconf_zone_write_granularity(BlockConf *conf); +bool blkconf_zoned(BlockConf *conf, Error **errp); bool blkconf_apply_backend_options(BlockConf *conf, bool readonly, bool resizable, Error **errp); =20 --=20 2.55.0 From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1787691585; cv=none; d=zohomail.com; s=zohoarc; b=I0wBNgPKPZeq+pizOdl80KVvFqfw9h5IhPu5q3Knzo4oGWsq6vKuqGY2r/7CFcYrYC9LvzeMkle5Quze8L0XVRTYSP3deBJa33oZZdrIhQGnelpHuLIaIMvLMW+iiedm9mUDmLVX4tyKUXn/Fj7jwcZi7lFgdSZb/Iq/36W+GFM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787691585; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ALKx1sZjhdbOJdc+aaF6o0PlVsXA7hiwS+FdiSVtflM=; b=geQdoavSsCyZhYSz1sZsIRRxTDkIrRLaChYTTc9v4o1mCsh+7qCYy2Rcf1IrfSeU42Dh2lH8Sv1li8ra1uKzCtXx48fgWlwYTJUovWXCtYR9nnFHwamMloDOtEeGfV/x2DIx21jJTYF+n6eJITS1FRT0AGDcUy3XVtmna0zx3SI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787691585750455.44757336813416; Tue, 25 Aug 2026 13:59:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyyDy-0001EV-L6; Tue, 25 Aug 2026 16:58:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDr-0001Ad-Vy; Tue, 25 Aug 2026 16:58:20 -0400 Received: from sea.source.kernel.org ([172.234.252.31]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDp-0003EF-4l; Tue, 25 Aug 2026 16:58:19 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id E250041889; Tue, 25 Aug 2026 20:58:15 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D958D1F000E9; Tue, 25 Aug 2026 20:58:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787691495; bh=ALKx1sZjhdbOJdc+aaF6o0PlVsXA7hiwS+FdiSVtflM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=eDoWRj+4rjJZsllHQCHwlXrPx/n0uF+e1XuAetFC3Bmi/Z501/XY735NnNOmZgMCB SezqVV7YSyd1Dq3srEdR/0blW73eo9/L323/DGDmfGqYOuaIfyisG4zujlbwXnvXjq R4LTBRu2/d879FGIALAh2CYxK/YMKJeTRPMFgNAK5tirDXOxvRLh+PN3htXYgVAL26 4qVas04YB9EcvvlLGZrjUT3+6CBv7JdLiAXt3jDBOJhgLqp9PUC9NDk8G6drlTzYrc bi8dwVGvMXPFE0pQOPMN0O5CTkYyvl6rt4v5O89HJRfNe8xnGbELC9sAYAY0Ru8tpV ysxecSXe/ASzg== From: Niklas Cassel To: Stefan Hajnoczi , Fam Zheng , Kevin Wolf , Hanna Reitz Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 07/12] block: reject zone appends that are not a multiple of the sector size Date: Tue, 25 Aug 2026 22:57:42 +0200 Message-ID: <20260825205748.679968-8-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825205748.679968-1-cassel@kernel.org> References: <20260825205748.679968-1-cassel@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=lists1p.gnu.org; Received-SPF: pass client-ip=172.234.252.31; envelope-from=cassel@kernel.org; helo=sea.source.kernel.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1787691587109158500 Content-Type: text/plain; charset="utf-8" Zone write pointers are tracked and reported in units of BDRV_SECTOR_SIZE, so an append whose data size is not a multiple of it would leave a write pointer that cannot be represented, neither in a BlockZoneDescriptor nor in the virtio and NVMe zone reports derived from one. Nothing states that invariant. file-posix, the only driver that carries out an append itself, does enforce it, but only as a side effect of checking each iovec against BlockLimits.write_granularity, which is never smaller than the sector size. That conflates two constraints: the sector granularity holds for every driver, whereas write_granularity describes a coarser requirement of the medium below a driver, and only a driver that has such a medium should express it. Check the invariant once in bdrv_co_zone_append(), so that it no longer rests on a driver that happens to have a granularity of its own to report. This is a lower bound, not the alignment that a guest has to observe. The block layer cannot know that one, because it also depends on the logical block size the device is configured with, which is a property of the frontend. The alignment that applies to a guest is the larger of the two, and it is the frontend that reports it, that validates requests against it, and that has to refuse a device whose write pointers do not satisfy it. Signed-off-by: Niklas Cassel Reviewed-by: Damien Le Moal --- block/io.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/block/io.c b/block/io.c index a916b236c3..705dc73d76 100644 --- a/block/io.c +++ b/block/io.c @@ -3350,6 +3350,16 @@ int coroutine_fn bdrv_co_zone_append(BlockDriverStat= e *bs, int64_t *offset, return ret; } =20 + /* + * Zone write pointers are kept and reported in units of BDRV_SECTOR_S= IZE, + * so an append that would leave a write pointer at a finer granularity + * cannot be represented. Drivers may impose a coarser granularity of = their + * own, see BlockLimits.write_granularity. + */ + if (!QEMU_IS_ALIGNED(qiov->size, BDRV_SECTOR_SIZE)) { + return -EINVAL; + } + bdrv_inc_in_flight(bs); if (!drv || !drv->bdrv_co_zone_append || bs->bl.zoned =3D=3D BLK_Z_NON= E) { co.ret =3D -ENOTSUP; --=20 2.55.0 From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1787691580; cv=none; d=zohomail.com; s=zohoarc; b=U/lbw+qIFQvTFtax+3P8hv1p+W003i+DPYZ76ZJlnEQ1jiCuw9PtWKRsJoxTrWjHu8UER4f1ULnNgfPSMNDCfy61ZShishU2dUJl5/1FXCkgietYjPoO/e+wJaGZjxD26xty5cgdrSYXk+gWlZZ/LQ2GXBCshLI1S54I1qbqVxY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787691580; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=gOPgC8KY7Ii6ZM09G4n19YbEJdFyZ8CvFdrBdhb/tsw=; b=FpkSBmlMX6U2grQLZmbbwYWD8GF6Fj0afpusiZMLD/qJ5s1JKl4xPdMBf9EU5YlQHyQPY+agoayU83NkyrbYbBaDRT6hwMNg26hR86Vt18x7WVLAWXLL0bLc7JZ3G9oNqFfCPpftCoHpw8zsRQELCrYjDYbO3/Ud70yMkZ3YfVs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787691580610999.675901332896; Tue, 25 Aug 2026 13:59:40 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyyE1-0001Gj-7N; Tue, 25 Aug 2026 16:58:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDv-0001D2-Se; Tue, 25 Aug 2026 16:58:24 -0400 Received: from sea.source.kernel.org ([2600:3c0a:e001:78e:0:1991:8:25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDs-0003Eb-2R; Tue, 25 Aug 2026 16:58:21 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 2D3D84082B; Tue, 25 Aug 2026 20:58:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4F8E91F000E9; Tue, 25 Aug 2026 20:58:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787691498; bh=gOPgC8KY7Ii6ZM09G4n19YbEJdFyZ8CvFdrBdhb/tsw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=m3tC0Us6woYfNN/FRz3/G/WjUUzw9HAaTEOdqPMKAd8NEZ2P1vV3RODeIgSaaAwHc Acn3y0f0SXdVeq+Z1seDray24ozp9SkEfB6Ie5I3NZ1RKJnAzPKsBP5X9rGhFqP06F 2RBGtqY+IzhysVGiI/dN7z3DWi4emVeN+nnxUVTqQo90kDcoluPvrlKcXiQCxll6ot 24pNqI/oW9dDuC4u1u79NuCCAFzLsZnnLrUNoUNV8QvHKtnLd2+CK/j3oruNS1gcli XcppJDPW+Pt3OT1BNWhMSlmU6h45jMbN9jGCB5wc0Zbp1+XEDrpcAotdmYMp81LtAX TF78KuiHLSsVQ== From: Niklas Cassel To: Stefan Hajnoczi , Kevin Wolf , Hanna Reitz Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 08/12] file-posix: remove the zone append write granularity check Date: Tue, 25 Aug 2026 22:57:43 +0200 Message-ID: <20260825205748.679968-9-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825205748.679968-1-cassel@kernel.org> References: <20260825205748.679968-1-cassel@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=lists1p.gnu.org; Received-SPF: pass client-ip=2600:3c0a:e001:78e:0:1991:8:25; envelope-from=cassel@kernel.org; helo=sea.source.kernel.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1787691581008158500 Content-Type: text/plain; charset="utf-8" The check rejects a zone append whose individual iovec lengths are not multiples of the zone write granularity. That is stricter than the constraint it is meant to enforce, which applies to the size of the request as a whole. A request whose total is properly aligned but which is split across, say, a 512 byte and a 3584 byte iovec is refused here, even though the iovec boundaries do not survive into the scatter gather list that reaches the device. Nor is the driver the right place to enforce it. The kernel and the device validate writes to a sequential zone themselves, which is why the same function already passes the request length down without comparing it against BlockLimits.max_append_sectors. The sector granularity that holds for every backend is now checked once in bdrv_co_zone_append(), and a frontend enforces the granularity it advertises to its guest. Drop the check. BlockLimits.write_granularity is now set in one place, by this driver from the zone_write_granularity queue attribute, and read in one place, by the frontend that reports it. Signed-off-by: Niklas Cassel Reviewed-by: Damien Le Moal --- block/file-posix.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/block/file-posix.c b/block/file-posix.c index c0d6ee30e4..f267513a4e 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -3593,8 +3593,6 @@ raw_co_zone_append(BlockDriverState *bs, BdrvRequestFlags flags) { assert(flags =3D=3D 0); int64_t zone_size_mask =3D bs->bl.zone_size - 1; - int64_t iov_len =3D 0; - int64_t len =3D 0; =20 if (*offset & zone_size_mask) { error_report("sector offset %" PRId64 " is not aligned to zone siz= e " @@ -3602,20 +3600,8 @@ raw_co_zone_append(BlockDriverState *bs, return -EINVAL; } =20 - int64_t wg =3D bs->bl.write_granularity; - int64_t wg_mask =3D wg - 1; - for (int i =3D 0; i < qiov->niov; i++) { - iov_len =3D qiov->iov[i].iov_len; - if (iov_len & wg_mask) { - error_report("len of IOVector[%d] %" PRId64 " is not aligned t= o " - "block size %" PRId64 "", i, iov_len, wg); - return -EINVAL; - } - len +=3D iov_len; - } - trace_zbd_zone_append(bs, *offset >> BDRV_SECTOR_BITS); - return raw_co_prw(bs, offset, len, qiov, QEMU_AIO_ZONE_APPEND, 0); + return raw_co_prw(bs, offset, qiov->size, qiov, QEMU_AIO_ZONE_APPEND, = 0); } #endif =20 --=20 2.55.0 From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1787691569; cv=none; d=zohomail.com; s=zohoarc; b=L//CnfyIkEQoMZJUqgVgbRZNTo51pKm1WO2FlreUBuT1yU5EdqRqo5zPZetUFvMEFtu7hkiJE4hgsZu6hu9OcjKTzBT/Gdnnm14bspbuRwRx1dYDsyHU6axm7r7lb/ifGlDxrHluMy4YUUwVIljRLTFgn45Ap3MMLXHmUkEQwX8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787691569; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=elBDym+odsFk7BBWDv9UsTDx8JlrqI3ofGnXzRMCW5M=; b=J5FRkzxNhENKNU6V09uSRh+RVS5rRDBtYzzWqI7s7s5bfuBPUbJM/7KACC6ixF2efJpGEIvLiaxMGYUGRMX1KPGg9X+DbDRCeUfaaGer30xj2eICP9LUzpUQBTsxTJPehvLuFXpXzCfEVfekcgEF4tJm+JEhjHSmMpSwPnceqvM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787691569312534.476950536231; Tue, 25 Aug 2026 13:59:29 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyyE0-0001GL-RT; Tue, 25 Aug 2026 16:58:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDw-0001DX-KO; Tue, 25 Aug 2026 16:58:24 -0400 Received: from sea.source.kernel.org ([172.234.252.31]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDt-0003EF-5K; Tue, 25 Aug 2026 16:58:22 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 6C1614199B; Tue, 25 Aug 2026 20:58:20 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8EC121F000E9; Tue, 25 Aug 2026 20:58:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787691500; bh=elBDym+odsFk7BBWDv9UsTDx8JlrqI3ofGnXzRMCW5M=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=M+vUtakZ+ToseNb8BWQFoVxktN7GccaOuJUp1X5xbvK22rP02Vb497+FdV0eEmYlm POYb/yr+SAe1LJYLfrxdnknIpEKPmvRBonB22Owcmg5+iSq2f77AlCpALFBWjjL8D+ /ofycqujMAJGLce8p57eZvZy1nQVeJCqOZg3sY3U4tdLCDdFSMfAt8rYQtP9WXr8Nt 48DIAbMkuqDkl+G5qGR5lIbd8KVepZJegT4jlvDQJ+NiSWNXUwiv2je8xpfJVUA+TT XqZx4gIWDUQdmo1OBg66uJxpYfbDyNKCVFMNoFxdbajpMzdTigOf0DR0w/wcm9Jpt7 ByPoJUCfKQHeg== From: Niklas Cassel To: Stefan Hajnoczi , Kevin Wolf , Hanna Reitz Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 09/12] file-posix: base the zone append limit on the transfer limit Date: Tue, 25 Aug 2026 22:57:44 +0200 Message-ID: <20260825205748.679968-10-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825205748.679968-1-cassel@kernel.org> References: <20260825205748.679968-1-cassel@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=lists1p.gnu.org; Received-SPF: pass client-ip=172.234.252.31; envelope-from=cassel@kernel.org; helo=sea.source.kernel.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1787691570953158500 Content-Type: text/plain; charset="utf-8" The zone_append_max_bytes queue attribute is the largest REQ_OP_ZONE_APPEND that the device accepts, and Linux has no interface for issuing one from userspace: include/uapi has no such operation, and every submitter of REQ_OP_ZONE_APPEND is in the kernel. Userspace writes to a sequential zone with an ordinary write at the write pointer. That is what this driver does. raw_co_zone_append() substitutes the write pointer of the zone for the offset and hands the request to raw_co_prw(), which reaches handle_aiocb_rw_vector() and issues a plain pwritev(). The kernel never sees a zone append, so the attribute describes a limit on an operation that is never issued. Nor is it a limit that this driver runs into. The kernel splits a write that exceeds the transfer limit rather than refusing it, so a larger append succeeds: on a null_blk device whose zone_append_max_bytes is 130560, a 16 MiB append completes and advances the write pointer by 16 MiB. Reporting the attribute only understates what the driver can do, because Linux derives it as a minimum that already includes max_sectors and chunk_sectors. Report max_hw_transfer instead, the limit that governs the write the driver actually issues. There is no use in telling a guest that it may append more than the device carries in one command, and a frontend then does not have to reason about how this driver implements an append in order to bound the value it advertises. On a null_blk device with max_hw_sectors_kb of 127 and zone_append_max_bytes of 130560, virtio-blk reports 255 sectors before and after. Signed-off-by: Niklas Cassel Reviewed-by: Damien Le Moal --- block/file-posix.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/block/file-posix.c b/block/file-posix.c index f267513a4e..e019cc3cd8 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -1488,10 +1488,15 @@ static void raw_refresh_zoned_limits(BlockDriverSta= te *bs, struct stat *st, } bs->bl.nr_zones =3D ret; =20 - ret =3D get_sysfs_long_val(st, "zone_append_max_bytes"); - if (ret > 0) { - bs->bl.max_append_sectors =3D ret >> BDRV_SECTOR_BITS; - } + /* + * raw_co_zone_append() carries out an append as an ordinary write at = the + * write pointer, so the zone_append_max_bytes attribute, which bounds= an + * operation that this driver never issues, does not apply. The kernel + * splits a write that is larger than the transfer limit rather than + * refusing it, but there is no use in telling a guest that it may app= end + * more than the device carries in one command. + */ + bs->bl.max_append_sectors =3D bs->bl.max_hw_transfer >> BDRV_SECTOR_BI= TS; =20 ret =3D get_sysfs_long_val(st, "zone_write_granularity"); if (ret >=3D 0) { --=20 2.55.0 From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1787691592; cv=none; d=zohomail.com; s=zohoarc; b=ZvWKvsi85rXBvNb4bhKsL2ezZejJ3/96RqDLGbDTprF2EH13s8Tr1sQOy4HfnkaFmrqIOxt/IDYZ8DMGwx8SsHYV01jkAP6bKV5E6gyjQTuqkrsQ2HZXxHbVnpfBMulUlbyxf1SBE9zbJtsTFtDRFKlzDjsmpjy89RDsMef/LGY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787691592; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=V1QJA5lXkrBozC1em/XCnvmxYkVTwAJshH7UJzNxDWw=; b=iRQ7x8wPLbktrM94r8DJziVeMytNGa5dsRM6wcPDNkJXU+kwtxPREbvdJ9Q0a9Zjtyc0CTal/Ii/kTb9UbLD0U563G/tqiEZ8Bf7flRnIS+brwFMfRWZDhLvakXQ2yPp3Phd+l0ivluEwwsHPmfY4a/pkZX77WHS9tkdgbilVg0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787691592089386.44379638982196; Tue, 25 Aug 2026 13:59:52 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyyE1-0001HY-Li; Tue, 25 Aug 2026 16:58:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDz-0001Fg-68; Tue, 25 Aug 2026 16:58:27 -0400 Received: from sea.source.kernel.org ([172.234.252.31]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDw-0003FC-BW; Tue, 25 Aug 2026 16:58:26 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id D5ADC4199E; Tue, 25 Aug 2026 20:58:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CD87C1F000E9; Tue, 25 Aug 2026 20:58:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787691502; bh=V1QJA5lXkrBozC1em/XCnvmxYkVTwAJshH7UJzNxDWw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=cmJY067T+/VXPyg0m8pxaASBmfGRnlF5U+vHe7QL6JiqH/5sB2QMfZEUSJ2DiZTeI mlKmnnOzBTQe1OJ9NreFXHA/6Ie+I1du24uIRiy8w0H56kaYIBLZcT6mvD5yqeWEss ViMa8f2ASPUM7WQ/8M6Ugx90T8+TW5vMSzrzmG7d1cyPVUQci4l/pFRGHtsimM3Mlg mE1EuHMpdxf8I/wwVANUmSp1uQKtnMC80J+a/0vpSEeIdwL7supedv047DPVsVsLnD kd4wRP2kqVAIdsnFmvDZai/Fue0QFpE4xwEPXINAhw+qV4BSOMU+5Vim7Y3n+ZL3ER HgBr0w4nI48lQ== From: Niklas Cassel To: Stefan Hajnoczi , "Michael S. Tsirkin" , Kevin Wolf , Hanna Reitz Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 10/12] virtio-blk: derive the maximum zone append size Date: Tue, 25 Aug 2026 22:57:45 +0200 Message-ID: <20260825205748.679968-11-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825205748.679968-1-cassel@kernel.org> References: <20260825205748.679968-1-cassel@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=lists1p.gnu.org; Received-SPF: pass client-ip=172.234.252.31; envelope-from=cassel@kernel.org; helo=sea.source.kernel.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1787691593078158500 Content-Type: text/plain; charset="utf-8" The max_append_sectors field of virtio_blk_zoned_characteristics must be set by the device to the largest zone append request that can be issued to it, and a value of zero tells the guest driver that zone append is not supported at all (virtio 1.4, 5.2.5.2). Linux refuses to attach a zoned device that reports zero. We pass BlockLimits.max_append_sectors straight through, which makes that field mean "zone append unsupported" when it is unset, rather than "this backend imposes no limit of its own". Only a backend that has a limit of its own has anything to put there. Derive the value instead. A backend limit is honoured when there is one, and otherwise the request is bounded by the zone size, since an append cannot cross a zone boundary, and by the largest request the block layer can carry. The result cannot be zero. A backend that carries out an append itself, rather than passing it to a device that has a limit of its own, is the one that knows how large a request its implementation can take, so it reports that in BlockLimits.max_append_sectors and this does not have to guess at it. Signed-off-by: Niklas Cassel Reviewed-by: Damien Le Moal --- hw/block/virtio-blk.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 61f7b3cdc1..6e9ee37ffc 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -498,6 +498,27 @@ typedef struct ZoneCmdData { }; } ZoneCmdData; =20 +/* + * The maximum zone append data size that the device reports to the driver= in + * virtio_blk_zoned_characteristics, in 512 byte sectors. + * + * A backend that has no limit of its own leaves BlockLimits.max_append_se= ctors + * at zero, in which case the limit is whatever else bounds the request: an + * append cannot cross a zone boundary, and the block layer cannot carry a + * larger one. The result is never zero, which the driver would read as zo= ne + * append not being supported at all. + */ +static uint32_t virtio_blk_max_append_sectors(VirtIOBlock *s) +{ + BlockDriverState *bs =3D blk_bs(s->blk); + uint64_t sectors; + + sectors =3D MIN_NON_ZERO(bs->bl.zone_size >> BDRV_SECTOR_BITS, + bs->bl.max_append_sectors); + + return MIN_NON_ZERO(sectors, BDRV_REQUEST_MAX_SECTORS); +} + /* * check zoned_request: error checking before issuing requests. If all che= cks * passed, return true. @@ -533,12 +554,8 @@ static bool check_zoned_request(VirtIOBlock *s, int64_= t offset, int64_t len, return false; } =20 - if (len / 512 > bs->bl.max_append_sectors) { - if (bs->bl.max_append_sectors =3D=3D 0) { - *status =3D VIRTIO_BLK_S_UNSUPP; - } else { - *status =3D VIRTIO_BLK_S_ZONE_INVALID_CMD; - } + if ((len >> BDRV_SECTOR_BITS) > virtio_blk_max_append_sectors(s)) { + *status =3D VIRTIO_BLK_S_ZONE_INVALID_CMD; return false; } } @@ -1300,7 +1317,7 @@ static void virtio_blk_update_config(VirtIODevice *vd= ev, uint8_t *config) virtio_stl_p(vdev, &blkcfg.zoned.write_granularity, blkconf_zone_write_granularity(conf)); virtio_stl_p(vdev, &blkcfg.zoned.max_append_sectors, - bs->bl.max_append_sectors); + virtio_blk_max_append_sectors(s)); } else { blkcfg.zoned.model =3D VIRTIO_BLK_Z_NONE; } --=20 2.55.0 From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1787691578; cv=none; d=zohomail.com; s=zohoarc; b=ENbveD9L8cu5lJn8P2/TV6mYZW8zrdZyPCAhKwoTIyfiDacC4gpFmK7Q4Y+r/V3rCOpdJCEnzH2CNsdtlr4I4BVy1vow3hP3dlRaSzbR7XNCjBpHa+1PL+9Kms/BNz4RES2V2yeD8dp3GLZs91v3w/7jXJJEUkhqIOoKhbnnL5s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787691578; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=kn7OvInryakcnhK7ztYQ924bSSICBL3RMBQHYHFt+QM=; b=HAUem2UT1NrFDF5tUrv2FglYj1cfA/u4/g2S838ztc6gD5/kwmYvo2jjvshGb5tYLtgmMGlxWtJwWXh7Sdflog23oNYb69m1K+UMZMiR4YYoYe0FUyOl1Qt43aE0ijpFgaq8EMGw2eDydQMgAnD1upjt7pnLocuJEfPm8tcVBUY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787691578415330.61058780211306; Tue, 25 Aug 2026 13:59:38 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyyE6-0001JQ-Qh; Tue, 25 Aug 2026 16:58:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyE1-0001HZ-Ke; Tue, 25 Aug 2026 16:58:29 -0400 Received: from sea.source.kernel.org ([172.234.252.31]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyDy-0003EF-UW; Tue, 25 Aug 2026 16:58:28 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 200404199C; Tue, 25 Aug 2026 20:58:25 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 42CA51F000E9; Tue, 25 Aug 2026 20:58:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787691505; bh=kn7OvInryakcnhK7ztYQ924bSSICBL3RMBQHYHFt+QM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Uc99Bf+ErCOLtTA49yNjDiusLBUdopI1jDlEFtCU00Y0Cypvk1hE7vz3qNwXGzdAn z334k2ZwFEb8ype4Ns0uwoIzD9b+zowb3UDyRWeJJkbbkLdx0sWxaHqXgXYH6Z910i /pVwZgin/dfjingV897bY71HfwOMnEXaWVDEiFGgwjjI/tSH9ttc5twJzy6ImZSSOZ NV78/TfksCxsJikkxwlQxOmM8VcI6K50qXbNsNn2O74cdqw8qtEfbirXcFi9395cvH BpUQjmj1cswvGUT7FxLMaquaDfGzardto/TpgwYbWmRfuzjnG965v/lBzaIZiRXlbM t+5NiSJAlDgSg== From: Niklas Cassel To: Stefan Hajnoczi , Kevin Wolf , Hanna Reitz Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 11/12] file-posix: reject a zone append past the device capacity Date: Tue, 25 Aug 2026 22:57:46 +0200 Message-ID: <20260825205748.679968-12-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825205748.679968-1-cassel@kernel.org> References: <20260825205748.679968-1-cassel@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=lists1p.gnu.org; Received-SPF: pass client-ip=172.234.252.31; envelope-from=cassel@kernel.org; helo=sea.source.kernel.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1787691579139158500 Content-Type: text/plain; charset="utf-8" raw_co_zone_append() checks that the offset it is given is aligned to the zone size, but not that it names a zone of the device. raw_co_prw() then derives a zone index from it and reads that entry of the write pointer array, so an offset past the end of the device reads past the end of the array. bdrv_co_zone_append() does not catch it either: bdrv_check_qiov_request() bounds the request against BDRV_MAX_LENGTH, which has nothing to do with the size of this device. A guest cannot reach it, because check_zoned_request() in virtio-blk rejects an out of range offset first, but qemu-io and any other caller of blk_co_zone_append() can: $ qemu-io --image-opts -n driver=3Dhost_device,filename=3D/dev/nullb0 \ -c "zap -p 0x100000000000 0x1000" Segmentation fault On a null_blk device with 1000 zones of 256 MiB, that offset yields zone index 65536 and reads 512 KiB beyond an 8000 byte allocation. Reject an offset that lies outside the device. That also bounds the zone index that raw_co_prw() derives from it, so its write pointer lookup stays inside the array. Fixes: 4751d09adcc3 ("block: introduce zone append write for zoned devices") Signed-off-by: Niklas Cassel Reviewed-by: Damien Le Moal --- block/file-posix.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/block/file-posix.c b/block/file-posix.c index e019cc3cd8..85d735c079 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -3597,8 +3597,15 @@ raw_co_zone_append(BlockDriverState *bs, QEMUIOVector *qiov, BdrvRequestFlags flags) { assert(flags =3D=3D 0); + int64_t capacity =3D bs->total_sectors << BDRV_SECTOR_BITS; int64_t zone_size_mask =3D bs->bl.zone_size - 1; =20 + if (*offset >=3D capacity) { + error_report("*offset %" PRId64 " is equal to or greater than the " + "device capacity %" PRId64 "", *offset, capacity); + return -ENOSPC; + } + if (*offset & zone_size_mask) { error_report("sector offset %" PRId64 " is not aligned to zone siz= e " "%" PRId64 "", *offset / 512, bs->bl.zone_size / 512); --=20 2.55.0 From nobody Sat Sep 26 21:35:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1787691550; cv=none; d=zohomail.com; s=zohoarc; b=XLUHrf/3ARWY+RmnVZFVJWw9mMSSyAlar5/WcZvxRR33AJrCQuh6SIDZIPZE20y/gwErycuZp0tWMft5OmOPDyzsHfL2pMc7GyFQF6E2NZ6IYxSawlUhhXst8mDCDLjnI6+8mOegA2Zu8UmWMBGnulxptXdVPsSQxE1EpJgcaec= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787691550; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=M7wb7uQGpFZypS1kuI5SudHeCe6U3M7sNK42IUiMtfc=; b=lcOBcOmLch86hfNs2UZTE+nizKpZGt+FJ+c6FbEjtcd0wWREsfuNjPDx8QyQtM/byc3B2a05yihNWu1NBK70RHCy6+FDfwo0ux+KdLolhBDGxosp/4MEIvXmRNM7c6F3BmDP2EB44KMLi5R6mTyTwraxnVflDsVJn0N0OHobMiA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787691550848620.0121849907057; Tue, 25 Aug 2026 13:59:10 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wyyE9-0001Kq-CH; Tue, 25 Aug 2026 16:58:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyE3-0001Ia-HZ; Tue, 25 Aug 2026 16:58:31 -0400 Received: from sea.source.kernel.org ([172.234.252.31]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wyyE0-0003FC-8Z; Tue, 25 Aug 2026 16:58:30 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 5E48E4005A; Tue, 25 Aug 2026 20:58:27 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 814561F000E9; Tue, 25 Aug 2026 20:58:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787691507; bh=M7wb7uQGpFZypS1kuI5SudHeCe6U3M7sNK42IUiMtfc=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Iu6ScVBp4P14oVPfVSyRL8UY0WLmxLpuN+sgFwXqO6YQOWTwZIRvCLEStNo6WBuXT +3BdBoOz/gjHpM+i41shsV5Kv8nQdKGV1ZmeG3xJAYW9EgnlnUyvQTDUjPhpHqW1RK FY6o1EatU47eSQjKxNBSS54bIdx86h6wHQk2rdguRGYXkZAFXt16VfVge+UIeYT/yE BvHbr8PKmw+g+BcEzzmb5wL4wBXnWe2Vauq6NoHdLIW19WnNbnT3S8mJAFEr3lkTgd 859Ynnsk6QF54kvihs087J05tGiMfZ+c0OwOco+s92ZOcqrSthl2pun/SGABnN6eEc kCOEH6PHR4q7g== From: Niklas Cassel To: Stefan Hajnoczi , Kevin Wolf , Hanna Reitz Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 12/12] file-posix: reject a zone append to a full or conventional zone Date: Tue, 25 Aug 2026 22:57:47 +0200 Message-ID: <20260825205748.679968-13-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825205748.679968-1-cassel@kernel.org> References: <20260825205748.679968-1-cassel@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=lists1p.gnu.org; Received-SPF: pass client-ip=172.234.252.31; envelope-from=cassel@kernel.org; helo=sea.source.kernel.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1787691553396158500 Content-Type: text/plain; charset="utf-8" raw_co_prw() replaces the offset of a zone append with the write pointer of the addressed zone, which assumes that the stored value names a position inside that zone. It does not in two cases. A full zone has its write pointer recorded at the end of the zone, since get_zones_wp() stores start + len for BLK_ZONE_COND_FULL. That is the first sector of the following zone, so the append is submitted there. The kernel accepts it whenever that zone is empty, because it is a legal write at its write pointer, and the completion path advances the wrong zone because it recomputes the zone index from the replaced offset. The data is written to a zone that was never addressed and success is returned: zone 2 finished, then a 4 KiB append to zone 2: After zap done, the append sector is 0x180000 <- zone 3 zone 2: wptr 0x180000, zcond:14 (full) zone 3: wptr 0x180008 <- advanced A conventional zone has no write pointer at all, and its array entry carries only the type marker in the top bit, so the offset becomes negative and the write fails with EINVAL. That is harmless but it reports nothing about the actual mistake. Reject both while the write pointer lock is held, since the state has to be read and acted on atomically. check_zoned_request() in virtio-blk refuses an append to a conventional zone, so that case needs a caller that goes to the driver directly, but nothing there examines whether a zone is full, so a guest can reach the misdirected write. Fixes: 4751d09adcc3 ("block: introduce zone append write for zoned devices") Signed-off-by: Niklas Cassel Reviewed-by: Damien Le Moal --- block/file-posix.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/block/file-posix.c b/block/file-posix.c index 85d735c079..135e60751f 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -2565,8 +2565,34 @@ raw_co_prw(BlockDriverState *bs, int64_t *offset_ptr= , uint64_t bytes, bs->bl.zoned !=3D BLK_Z_NONE) { qemu_co_mutex_lock(&bs->wps->colock); if (type & QEMU_AIO_ZONE_APPEND) { - int index =3D offset / bs->bl.zone_size; - offset =3D bs->wps->wp[index]; + uint32_t index =3D offset / bs->bl.zone_size; + uint64_t wp =3D bs->wps->wp[index]; + uint64_t zone_end =3D + MIN((uint64_t)(index + 1) * bs->bl.zone_size, + (uint64_t)bs->total_sectors << BDRV_SECTOR_BITS); + + /* + * The write pointer of the addressed zone becomes the offset = of + * the write, so it has to name a position inside that zone. It + * does not for a conventional zone, which has no write pointe= r and + * stores a type marker in the top bit instead, and it does no= t for + * a full zone, whose write pointer is reported at the zone en= d. + * Either would send the data to a zone that was never address= ed. + */ + if (BDRV_ZT_IS_CONV(wp)) { + error_report("zone append at offset 0x%" PRIx64 " addresse= s a " + "conventional zone", offset); + qemu_co_mutex_unlock(&bs->wps->colock); + return -EINVAL; + } + if (wp >=3D zone_end) { + error_report("zone append at offset 0x%" PRIx64 " addresse= s a " + "full zone", offset); + qemu_co_mutex_unlock(&bs->wps->colock); + return -ENOSPC; + } + + offset =3D wp; } } #endif --=20 2.55.0