From nobody Sat Sep 26 20:50:33 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=1788378334; cv=none; d=zohomail.com; s=zohoarc; b=Og/MmlJSJDNntV59Dxy5+y6jeDCV0Qe94rpG09zVpRmAWhCQ/cr/JH/ipCtXtp6/Yj2sjgFf8b3srPlHbB0GlKVHyRF5AVVpLvlF7Jjoz35wkgqQfo38Gc0tXLbnmICxYprQv+CUHGgNIsyTlNzTA4oAOkYtpMlFs7fRGqOUIUU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788378334; 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=TO+F2pc2vn4cH6gj+eUGA+TbOU46rfxX7z+qzRTHsOk=; b=MhxdnIjiOcjJ+k6tEuJk0Lwpl5VhoHoPvahq+/VwhJul4qhrv7qFcgERxkHhIgQ39sszUlTHvFS+7jrqX53vPmmZfhSAyR6JV0Hc0DqRxj6kQtBGMwSpetc4NQwQ6TjBKqCTYnnebkHP3C5UG1epJRW5WlhmaKvqDF/G6W5EZlU= 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 1788378334811528.1249497446191; Wed, 2 Sep 2026 12:45:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x1qtC-0000Q8-TB; Wed, 02 Sep 2026 15:44:54 -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 1x1qtB-0000Op-6W; Wed, 02 Sep 2026 15:44:53 -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 1x1qt9-0005zF-CY; Wed, 02 Sep 2026 15:44:52 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by tor.source.kernel.org (Postfix) with ESMTP id 85F58600D4; Wed, 2 Sep 2026 19:44:43 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 636E31F000E9; Wed, 2 Sep 2026 19:44:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788378283; bh=TO+F2pc2vn4cH6gj+eUGA+TbOU46rfxX7z+qzRTHsOk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Ijvjjvf65bkvEt+MCXS1aFadfKNdAqAIOJlMpT1Wk/k20H9BSqoNrpT/ZZ9pSVnNt ycHMIC2A2ZUJnv1Tur3x9vR+EWld+E0aijWIKUp7kDEBnkrpmEjLIdAnDR7TUtFZZq w7REd8woljmiOSEYJefo4sstzCkO7OP52JSpLq1TylqarXNXh+lJn8BavmKsGE/aT5 4JlnBAfjbjlO8XQrHvSQeDv0cR3X0Tv/XcRXk9IFMlqiApwsw073bL97YxSFTJ5oB3 5cWGCqDxbo/CoNjk6oi4naILJasl2uh1z4PreHPMRW4Yy2HqYPKUyMImcUYjjB1oAC RoyQ63PquMvIg== 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 v2 01/11] block: widen BlockLimits.zone_size to uint64_t Date: Wed, 2 Sep 2026 21:44:12 +0200 Message-ID: <20260902194423.759355-2-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260902194423.759355-1-cassel@kernel.org> References: <20260902194423.759355-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: 1788378335424158500 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 Reviewed-by: Damien Le Moal Signed-off-by: Niklas Cassel --- 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 9aad156aad..c0d6ee30e4 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 20:50:33 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=1788378350; cv=none; d=zohomail.com; s=zohoarc; b=WrpTF6jzD2uYiXZvmdgDMhZEKIZsrhq1XJ1Z3BBzxONUvEzT+px3HR+tpQxz/k7y77Evy784YNyVEFUAYAJ1mNWjI4SjdpOGuMuKxeT+RrOxo0GR6Bc2nFiRaEGfUbYOMCbCgX57ATjX/xrnbIrnZ/OQfoXHAwrak6M/121FpyU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788378350; 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=TFg7avD/j58roO41WzcRhKlbi6ueX70eH3NQ2e75uBA=; b=mUraEmf9XOloQ9FwNYGDAQnrqVgJB90+i5N3NunYchYS7jbwDis6UdcbkCrfRufhb4xKwQfYHV1QTzuL1kWsbjDudRk/Vgle/dk0GtrTK1bp/qx9t4DtLxSpnrr23LHWnwmkhX+azQrp7pGvFMcHXZ2LzXTFAeHmvEZdTu8/ul8= 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 1788378350506748.6424335168456; Wed, 2 Sep 2026 12:45:50 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x1qtF-0000Sw-Gg; Wed, 02 Sep 2026 15:44:57 -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 1x1qtD-0000RO-J1; Wed, 02 Sep 2026 15:44:55 -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 1x1qtB-0005zN-Te; Wed, 02 Sep 2026 15:44:55 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by tor.source.kernel.org (Postfix) with ESMTP id 251B3601EF; Wed, 2 Sep 2026 19:44:46 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C816D1F000E9; Wed, 2 Sep 2026 19:44:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788378285; bh=TFg7avD/j58roO41WzcRhKlbi6ueX70eH3NQ2e75uBA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=G8/8s3SUAnKS2Np3hrA/o6z+mooDhcO0H5Wo9qkXWcvvNpbYTsI6/CIwu1xxj1HFg jOJMCLNdG2SrtpzUmsUl3SJsUIyTpp7w+L644gmp3g7lSMpvJGnbnr/g7Dl0rSS0BS W9haK+UbQ/p7Al9EqEK4ZtYNTH5eAhDXg9qjTVooYVAIFO+UakxMgosbVZOE4ep5T9 R5XNk4innzBL3LlbvDl3mwby9GFnMH2LQEJ4QKy9lUvnryZz4aJQ784Fgbi1BSb5ev P4I5VH/OOF6WSYox+P8MTk3bwSiqSzCUjWqqEenhaDX5AdZmsT1P/1Ly6HNJTwG2Jq wZchvnIqQxOnA== 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 v2 02/11] virtio-blk: do not merge requests across a zone boundary Date: Wed, 2 Sep 2026 21:44:13 +0200 Message-ID: <20260902194423.759355-3-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260902194423.759355-1-cassel@kernel.org> References: <20260902194423.759355-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: 1788378352130154100 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/read must stay within a single zone (virtio 1.4, 5.2.6.1). 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: Damien Le Moal Reviewed-by: Stefan Hajnoczi Reviewed-by: Niklas Cassel Signed-off-by: Niklas Cassel --- 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..ffcd327803 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_nr_sectors, 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) { + /* + * 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_nr_sectors =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_nr_sectors) !=3D + (end_sector / zone_nr_sectors); + } else { + zone_cross =3D false; + } + /* * 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 20:50:33 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=1788378362; cv=none; d=zohomail.com; s=zohoarc; b=WMSlikD/S1caWAvcLBqLbNEok2UTr3KGc9PEQ3VuPtYbprwSNCZ+/UjoFhvp4FaOgBoofjCXb131B2d3TJcbfHbBQvSgZa6/NbJjlv9ZdTTci5JXczAu1o85fUxLdy41WarHC0+JFu877ITFEZl/vUlP76o6yKs0WBtR/Xmo/0o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788378362; 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=IGcgE/4NFaLV5tyZlvJo73z07UAWAIkatyuzrJ46im0=; b=GCvNtDQtvGw0qBa3/qfWxZdSjT6EDL8vflOalY7uaSpqR3u+0w0VexsGB9KBuriCcl+Lz7DtM4aiNzs3lJ8j4kNOPixNcUTv5BhpVZvspyUkBG2Zc3P/f4igiK8ka4pWQXlEx3YnEaGrFmaHCASrW9QLBIieVBmfhEn+DN/WqZ4= 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 1788378362947365.59923162141286; Wed, 2 Sep 2026 12:46:02 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x1qtC-0000Q6-HV; Wed, 02 Sep 2026 15:44:54 -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 1x1qtA-0000OE-N8; Wed, 02 Sep 2026 15:44:52 -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 1x1qt8-0005zT-Sy; Wed, 02 Sep 2026 15:44:52 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id E8D6A43889; Wed, 2 Sep 2026 19:44:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 66E221F000E9; Wed, 2 Sep 2026 19:44:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788378288; bh=IGcgE/4NFaLV5tyZlvJo73z07UAWAIkatyuzrJ46im0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=B6VIqMfpA1U60WS/vEJHfdtweT5EvvhzDWj0A+bi+h4VfxbSiHQmSFrUzPwYTYcb4 aLWkCT2kgsmWF9dSoah9FmtTNRVvklkvZ/2qvK1aB/YHefkHDDXPGQw470ESfj9baR XUqtdxiLUx0koYYs82mNe0LK/1eb45B3mlUCKOe1R8UpA+L9Kooi75nz5rGQcwa5Qy Pmv8ogsjiNt6s4U62RA110acPeZRCIOxhLVVK5kv9U3jzhpBB3ULMiJm35sAz7cEHI zDffE4ZJ/geBNWnSbd6imxaaVkR5VkEUa4jAN2n47zkqwPioQgstrjOg9+1ZSax6m/ R+PJTCH0J96GA== From: Niklas Cassel To: Stefan Hajnoczi , Kevin Wolf , John Snow , "Denis V. Lunev" , Hanna Reitz , "Michael S. Tsirkin" Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v2 03/11] virtio-blk: report the effective zone write granularity Date: Wed, 2 Sep 2026 21:44:14 +0200 Message-ID: <20260902194423.759355-4-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260902194423.759355-1-cassel@kernel.org> References: <20260902194423.759355-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: 1788378364382154100 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") Reviewed-by: Damien Le Moal Signed-off-by: Niklas Cassel --- 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 ffcd327803..b22aed04a1 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 20:50:33 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=1788378374; cv=none; d=zohomail.com; s=zohoarc; b=ivGa9d6KgOgF8xRbeloH1nEjELVsBxBmqsLTeeiMFJ+hIMvtCc1zZr8kMLaZBZKruAuNDGQtAVbXUS6WhLPzrJq/qK9WJ0ysdOYhUsGfjlafe/9/rVnwBq5AU1DUa6aQTmEq1GcM9pT/JDmY//hC7adHVsNwsFSOFyHo6D7nGg0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788378374; 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=2YJPuwHYqNlX6D6HFRPrMD9ckno5hSCVxl5z3aaycTE=; b=DZTIU2+z9PLpxrEVAWE67kF/c3tTlD74mh5LwECWmFYp9j9ynYAMSZ+Td5rpZCHy3DY429D3r1jQD45xMaF3oknSn8o/MgkPYU2Kh4AQAo/FBKuvaQht3CPHjMguvpa4Q+k5IUGQ0u8pCU+6ejPaJ8Rc/X/ia1XfP4MDLaIKPMs= 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 178837837440378.2543180487861; Wed, 2 Sep 2026 12:46:14 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x1qtE-0000So-Um; Wed, 02 Sep 2026 15:44:56 -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 1x1qtD-0000QG-7T; Wed, 02 Sep 2026 15:44:55 -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 1x1qtB-0005zr-Hc; Wed, 02 Sep 2026 15:44:54 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by tor.source.kernel.org (Postfix) with ESMTP id AC0BA600D1; Wed, 2 Sep 2026 19:44:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5BA431F000E9; Wed, 2 Sep 2026 19:44:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788378291; bh=2YJPuwHYqNlX6D6HFRPrMD9ckno5hSCVxl5z3aaycTE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=K5sC+B8py39Q0xoaWvih8E05Wmm7XcxcFd1FOyj3XdcuZUQAe/405TISX3dIgG9lR 2yZA70qdn2WzLUo/4LdedYs3sE9MfQLUeSg9QCNouXDTtLa631iuv296071puiaGmZ /FM43djkIWzG36uR72UOOQ8xNi1T3cDO5YGyZFrx1x/4nQFJR9wPScl9iMi2Ynca6O 8ATW4WeO20uKe3y4tjDfJonqKC4fcxMUr4+w2snP3QKeKj6LJ/nzr2CjKDe6DqMAJk /BnoLmVu/JAyZfVcD/eBpvBi7jB6ujVhQsQg7/fZP6jh5CC9fTHAdgiROkV3wR/Qck ULKnO70Yd2Iuw== From: Niklas Cassel To: Stefan Hajnoczi , Kevin Wolf , "Michael S. Tsirkin" , Hanna Reitz Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v2 04/11] virtio-blk: check the write granularity of writes to sequential zones Date: Wed, 2 Sep 2026 21:44:15 +0200 Message-ID: <20260902194423.759355-5-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260902194423.759355-1-cassel@kernel.org> References: <20260902194423.759355-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: 1788378375627158500 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 | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index b22aed04a1..247af53ae2 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -398,6 +398,32 @@ static bool virtio_blk_sect_range_ok(VirtIOBlock *dev, return true; } =20 +/* + * Both the offset and the size of a write to a sequential zone must be a + * multiple of the write granularity that the device reports. Conventional + * zones are not constrained. The zone index is derived from a guest suppl= ied + * sector, so this must only be called once virtio_blk_sect_range_ok() has + * bounded it. + */ +static bool virtio_blk_zone_write_granularity_ok(VirtIOBlock *dev, + uint64_t sector, size_t s= ize) +{ + BlockDriverState *bs =3D blk_bs(dev->blk); + uint64_t offset =3D sector << BDRV_SECTOR_BITS; + uint32_t wg_mask; + + if (bs->bl.zoned =3D=3D BLK_Z_NONE) { + return true; + } + + wg_mask =3D blkconf_zone_write_granularity(&dev->conf.conf) - 1; + if (!(offset & wg_mask) && !(size & wg_mask)) { + return true; + } + + return BDRV_ZT_IS_CONV(bs->wps->wp[offset / bs->bl.zone_size]); +} + static uint8_t virtio_blk_handle_discard_write_zeroes(VirtIOBlockReq *req, struct virtio_blk_discard_write_zeroes *dwz_hdr, bool is_write_zeroes) { @@ -522,7 +548,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 +937,15 @@ static int virtio_blk_handle_request(VirtIOBlockReq *r= eq, MultiReqBuffer *mrb) return 0; } =20 + if (is_write && + !virtio_blk_zone_write_granularity_ok(s, req->sector_num, + req->qiov.size)) { + virtio_blk_req_complete(req, VIRTIO_BLK_S_ZONE_UNALIGNED_WP); + 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 20:50:33 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=1788378397; cv=none; d=zohomail.com; s=zohoarc; b=G/T9de3dE9N3UvhHDtB9TSU5G9tYCdCkn42MzcoI1BROZjl/S84HAeNKcp5SS+f5NVZ0rLFKLd3kIB7TF/aX4qrAGgwGPDihnlUU2cvqfpZBT1iHsQlevArpSunpxCGHpfkwTvOtOm9F9C2x6pLPphdp5IQ1qSjjcTONQnoGbD4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788378397; 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=w/aPSThE5ovvppFdN3eiUtqJn9HPpRm5Mq+1bi/iKHw=; b=ILsmSid6EQEhqxI7tOPPolbSJbqO9UJhT6XjQeFJbg0GWTw+G0WbUHNEhbgm5dceyv+Xx3B5rJz+Mvvisbb9Id9qbFpVRvj+03BtbJOn7ncQqu7KqNSjtliuY++0d99cqfuhYCGak9Cz3CNQD6MyxrUrkF0VNcih7vf3vUP5L8M= 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 1788378397541577.8968278637728; Wed, 2 Sep 2026 12:46:37 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x1qtH-0000U6-SL; Wed, 02 Sep 2026 15:44:59 -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 1x1qtF-0000T2-MX; Wed, 02 Sep 2026 15:44:57 -0400 Received: from tor.source.kernel.org ([172.105.4.254]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x1qtD-00061C-T8; Wed, 02 Sep 2026 15:44:57 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by tor.source.kernel.org (Postfix) with ESMTP id A7B54600D4; Wed, 2 Sep 2026 19:44:54 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id EE8031F000E9; Wed, 2 Sep 2026 19:44:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788378294; bh=w/aPSThE5ovvppFdN3eiUtqJn9HPpRm5Mq+1bi/iKHw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Ob9Eof7clsRPX4li2d1TQpoWVwU1C6rdpqvWLMlhtMLkiOouUcROKgDxDG5EdzofV B/s50mG91E5PyEKVLp+8739nJgF+2MwAp8gO+6d35pyC1adAIDiy7vVidJZmgzHt93 i0tIOqYVMnQ0TqrlkHSzmdfG0TfoNNd18MXA8uJJ/r+FsabEs54Yf6LAJsIB6iOrYV B+i9k8LhHlmzteO2EtCzmEfl7ky8/7ut4m8nH1TQZlnGAIcYQioK4MjBnjEDyaptg3 kowvrZN4588r7bafvzyb6pkNLWiDZBtk/3kPACcmOJ50JZqdqqWt2V+XQoxfU/0F7D L4PHOq60kdUbQ== From: Niklas Cassel To: Stefan Hajnoczi , Kevin Wolf , John Snow , "Denis V. Lunev" , Hanna Reitz , "Michael S. Tsirkin" Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v2 05/11] hw/block: reject a zoned device whose write pointers are unaddressable Date: Wed, 2 Sep 2026 21:44:16 +0200 Message-ID: <20260902194423.759355-6-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260902194423.759355-1-cassel@kernel.org> References: <20260902194423.759355-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.105.4.254; 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: 1788378397730158500 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 Reviewed-by: Damien Le Moal --- 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..38bfdf8ffe 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_geometry(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 247af53ae2..f34d432e2b 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -1833,6 +1833,10 @@ static void virtio_blk_device_realize(DeviceState *d= ev, Error **errp) return; } =20 + if (!blkconf_zoned_geometry(&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..7282137e76 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_geometry(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 20:50:33 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=1788378394; cv=none; d=zohomail.com; s=zohoarc; b=Oe1n8BNQuY3kIamuHRGMY8swTbL8fp0KEDy0lJMB+w4KXNkL3RCb1cZZ837SYYU0QYU0x8DlRXhX+80f+S1IuBNwNCOcOWsfsouuHLV1fCSNB5ILAe0I6JTrkfjq0qiqWv9U/ihh6zsvsAt2DyjuirO4NAxFrAOdmAlk6Y9/IYA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788378394; 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=wyZPqLbbh9rym5im2traSqQISjkSVit9l7lAXdX6ud4=; b=b4YSlr8i8thohkAyWhyu751ADl7f3LfFEqLjW8x1McLz9WoMrfdslRIIwuKu/Gxvv6m2lmpNph9gTyEdxrFeD0G5kJ5PBWdhWyFxDt/nkhEB1Gmt7ofpOCz1O736kctGof1+bVdOy68LRtPOp4XQar6xAnDxz7ymb/HW/XlZ9E0= 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 1788378394081780.2751064079521; Wed, 2 Sep 2026 12:46:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x1qtK-0000Vh-Kg; Wed, 02 Sep 2026 15:45:02 -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 1x1qtI-0000UN-1d; Wed, 02 Sep 2026 15:45:00 -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 1x1qtG-00061c-Ce; Wed, 02 Sep 2026 15:44:59 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 144ED43CA7; Wed, 2 Sep 2026 19:44:57 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E28F81F000E9; Wed, 2 Sep 2026 19:44:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788378297; bh=wyZPqLbbh9rym5im2traSqQISjkSVit9l7lAXdX6ud4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=j0fZdoiL/Dlg+2joMc08mrnOaqwRiKR3EwnvOrnN2Ui/AtCPNSDRn7PGTIVuxBGY8 4a5VOv25kuqqSCaXL+vZOONcCkfHeVJMJRY2J5UJvnJaCWBxgl3i5Mw5dr5QCAVqz4 vi+EE+TeRzlmvfelu+weKcevNgvZDQweUy4bI/1gXe0aHqbimZXCpqfXt3q1f/e5ta ARR8jfMTtg7uMTag6SQ0aNzKjXYo/NqQZkpJNGMfLXmAis8bvzDRVMdoDrqjBOssAQ WWHM+kLcC6n3ODO3Ipkx/rP4cNYYZb+XBTIv0kHvUHzL1JxOFlTeLcT1iaBdyumMCs cdjxt8MlKG3Sw== From: Niklas Cassel To: Stefan Hajnoczi , Kevin Wolf , Fam Zheng , Hanna Reitz Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v2 06/11] block: reject zone appends that are not a multiple of the sector size Date: Wed, 2 Sep 2026 21:44:17 +0200 Message-ID: <20260902194423.759355-7-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260902194423.759355-1-cassel@kernel.org> References: <20260902194423.759355-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: 1788378395774158500 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. Reviewed-by: Damien Le Moal Signed-off-by: Niklas Cassel --- 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 20:50:33 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=1788378367; cv=none; d=zohomail.com; s=zohoarc; b=lM8zQHVF3jeX6lEZh1bNvyrfp4QMhMn++MS8qMXr+oXNLMIubT75BF4YTmpqAm6lLuLag76fJuwqwJZKdZ93Li2AexGO5feei5O0zLvRwaqJ6nbLI9jnT6jgJ98tks4/vKONHPOzxasodE57TITbcFNqRD0TRIKx2sbDb386X7Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788378367; 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=h9Qo5k3ykhgIn0JhKJQgJWLA0g5Mjf6BwJLZOuJOsus=; b=T1AqOaWColGBbcPfacCN26LE/5VMM3v5d62AlP5uA1DwaOrw0ZCGSmmLr72mG7gWNF6dCwIE/Opil1VvkMkJRQC05GlotzmmoIxna/ozQXN8lAFCbA+YyBR6coFXk51Sg+0c4JpW388GUuL7VV4FKuF14A0mxT9uKwHdFPSFKZM= 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 1788378367168317.6295965630803; Wed, 2 Sep 2026 12:46:07 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x1qtO-0000X2-MC; Wed, 02 Sep 2026 15:45:07 -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 1x1qtK-0000VG-9d; Wed, 02 Sep 2026 15:45:02 -0400 Received: from tor.source.kernel.org ([172.105.4.254]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x1qtI-00062K-Jh; Wed, 02 Sep 2026 15:45:02 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by tor.source.kernel.org (Postfix) with ESMTP id 9E027600D1; Wed, 2 Sep 2026 19:44:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7B2411F000E9; Wed, 2 Sep 2026 19:44:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788378299; bh=h9Qo5k3ykhgIn0JhKJQgJWLA0g5Mjf6BwJLZOuJOsus=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=gMIn3nuvwATWak+HdbI5ar41Y9/vzQwLoqw9s+zj3yT0i9NXEqqHoaSfJ4Dg95IYH qB/EVD85oU5M9jE7wA6GI2NdGWukJnmVzD3EwboK5qQvDOLrZ9aE3PWQW0inoY9eiV lgfBtsqwtwrTqvaToSWS3+d0b82nybYGuB0x512y6zALDOlL0xquUEfU1t+31ShQn2 ZDHGVphfHefrjdnCP7UTlQ7UMf3L8C8BvCQDF0owgHYLzo3GEwaUrJXc1sgcM3032Y FloDT8Hqbgnp7li4CLLz/1T/sO3tpLr7WHCZCKyz83ZtMFGf89b1kexd33W5ZzW3Md f+UYU40L22NWg== 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 v2 07/11] file-posix: remove the zone append write granularity check Date: Wed, 2 Sep 2026 21:44:18 +0200 Message-ID: <20260902194423.759355-8-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260902194423.759355-1-cassel@kernel.org> References: <20260902194423.759355-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.105.4.254; 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: 1788378370415154100 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. Reviewed-by: Damien Le Moal Signed-off-by: Niklas Cassel --- 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 20:50:33 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=1788378350; cv=none; d=zohomail.com; s=zohoarc; b=arlNrvh4c+sxwB4AyZQSyEoAOkb+b2qKvcS0OzCako8w/LQkjIgtPhWF7H8y4Mj+rqM/fLa8SUJ9Fu29RUcd9+s6DXdlUc8vtxLf9moCGTtrx6cZjoUmuT+uHdNt0ogv8f/ZgF5YsGRi9LirYKOPyuJIbX9BL0RussEtkMu4L1s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788378350; 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=PA7Yp0HhTd128mXFaQHf2upT6PMZf+sxSx5KKHH3HZs=; b=a4qaUrHQY2PFkF1sVU4ZPf12UKfMIzmwxtiyMsO989CyTVPM8PCHwNtoiVNSQnmuamHdB84g8IMjlvvpXENIEA2dGRWolOWS8aMvCVmZL8vOJJal+GuSO1lhp2N7Z5gagGB/oxEsP6Mqej6AVXHHYCavSApECAZosazKzv81DqI= 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 1788378350045890.0063833015879; Wed, 2 Sep 2026 12:45:50 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x1qtV-0000Yn-DC; Wed, 02 Sep 2026 15:45:14 -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 1x1qtM-0000WZ-Qv; Wed, 02 Sep 2026 15:45:05 -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 1x1qtL-00062t-4P; Wed, 02 Sep 2026 15:45:04 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by tor.source.kernel.org (Postfix) with ESMTP id 09A4C600D4; Wed, 2 Sep 2026 19:45:02 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id DA2791F000E9; Wed, 2 Sep 2026 19:44:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788378301; bh=PA7Yp0HhTd128mXFaQHf2upT6PMZf+sxSx5KKHH3HZs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=N5c12ZmeXK6pfu8Dh+3q+2yuliRkYYARURPpb3UzhIXMcCJsKvoxouzGz0Bv98gMZ ucpNwVbbBMAyedfb4qsI7xRfbwP7CQHxghFiS4BVewqOiZwTku5WwttwkRiF+hcmEb l4yn+hfU4VOkbjX2lqzF6pEkoC6js/Cu3lhiJSmp6jyziQND/BPzP9i7U54nOhA8o3 E0MIjK87gvSGnyEsH3hGQxKeIpzuLjMXoPVopN6r4jk6d2lox+TFB5rd9nKeo21VKP SC7ddPPjtDBVgLCS0D9OgkZths+xc45yypFSSuhbWPgkIpotg/f83Ot7gAUsfJh92Z notk5f2qHSA6g== 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 v2 08/11] file-posix: base the zone append limit on the transfer limit Date: Wed, 2 Sep 2026 21:44:19 +0200 Message-ID: <20260902194423.759355-9-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260902194423.759355-1-cassel@kernel.org> References: <20260902194423.759355-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: 1788378352194154100 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. Reviewed-by: Damien Le Moal Signed-off-by: Niklas Cassel --- 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 20:50:33 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=1788378418; cv=none; d=zohomail.com; s=zohoarc; b=hyMP2OE+fgTg7M5Tth8r3BLMYWvh8hKk1Hdf2YaZLVZA1JGdkAiDx5mbO4nNgPwzx8cGxGL8n4lz8xHBwkyF5ykYMtOWdjt+JWPLQDkSrEHXUfhLlyo60dm1yeTNhjojWe8epYEOHSUDhVqkoGOPxPcSIy+tJA749RIhSJwe8Fs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788378418; 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=TUzZqfR1ig5wvZkHz8lX6ALxKBm6YQTd5snIy28tktk=; b=ned7mTZHJis1xa0ABLvu+xOBV+0UQjp5ibaqTO6Qtw1e0q8OfdQErXMo739MCcbhEYSPtvIxR1+2IIZA6YyPpmzyMcDfOJk3EKpFFcxaC8JMVm2jgCdsVjgNzR+Cx9AGp7EGLlxFcTYTpi1a1DlDepMG9P6tQPGryvHlQ7iprK8= 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 1788378418748522.7811223624294; Wed, 2 Sep 2026 12:46:58 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x1qtX-0000ao-2o; Wed, 02 Sep 2026 15:45: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 1x1qtP-0000XC-M0; Wed, 02 Sep 2026 15:45:08 -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 1x1qtN-0006Ds-Sh; Wed, 02 Sep 2026 15:45:07 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 6E29140984; Wed, 2 Sep 2026 19:45:04 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 45D271F000E9; Wed, 2 Sep 2026 19:45:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788378304; bh=TUzZqfR1ig5wvZkHz8lX6ALxKBm6YQTd5snIy28tktk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=bvGhPgp+FRv2KOCEjD0k/4GttOLErmIhIdH1Hc2+YvKdTJYSxSQ/R165uSW4CfpTA RJUCclx5TJf4hIazvWSWmlPcVCT0WsTK0dDeRXbnE5fZesMB7+wtzmBpcJGqMngmIz ddfDI2lEzDAaWL7UNQJrz8xrhmiNloPt0VnHsEDc6wbD1RXJODfr8JhD5sq7/NpX/0 Uqa0No7pNdaGVgMyNfrN3SbzwK+k+eYMgE01dMyJ1cFBQ8Wic/MaIfBTRWIcBcE5FA JeyMGm9O3CqQuLL2CSMqmP6AuYa0xZ9h3ng7E5T1d2ntiUh6PPvMZg53RtfGw2d8gV LJ7VBRnGGlLhg== From: Niklas Cassel To: Stefan Hajnoczi , Kevin Wolf , "Michael S. Tsirkin" , Hanna Reitz Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v2 09/11] virtio-blk: derive the maximum zone append size Date: Wed, 2 Sep 2026 21:44:20 +0200 Message-ID: <20260902194423.759355-10-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260902194423.759355-1-cassel@kernel.org> References: <20260902194423.759355-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: 1788378421267154100 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. Reviewed-by: Damien Le Moal Signed-off-by: Niklas Cassel --- 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 f34d432e2b..7abe13919a 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -524,6 +524,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. @@ -559,12 +580,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; } } @@ -1312,7 +1329,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 20:50:33 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=1788378383; cv=none; d=zohomail.com; s=zohoarc; b=FqXSwSQS//rd5+sfqoAOzyQfMSbNZsA2NcmtG0FglMiy68RA3W1+UI76qx7dmKNZr/eAYBVQZQIENs3k51tuoJ0j655UYDIaVXGBrwBRk1GgNI3Q6cSwDNSo5skamPQEr/rzFUBxspnoaWdIwfO7DtplkaNW9PPF+DNvys2a4yk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788378383; 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=zrXu7dhERiW+wXiBbdy71b9VStVhzZds0WPzZYsva5E=; b=VcwtGIUoQ9VTR7flNCJJHX+5W4uyopMpcAyfuYvMRNE4farsy2A0Aou3WTcssgNXPUPc2+IUtdS1IVPKu4WYzB4fY/uZKNg/ymeMJURhl3YXU2NwhW5nx7S9s6NxC663GFJulM3BDlmNw9pFphs4nh83B6ov51WwQTnrPkZXbYA= 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 1788378383556615.6386466780712; Wed, 2 Sep 2026 12:46:23 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x1qtW-0000aP-G0; Wed, 02 Sep 2026 15:45:14 -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 1x1qtR-0000XW-R9; Wed, 02 Sep 2026 15:45:09 -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 1x1qtQ-0006EK-0V; Wed, 02 Sep 2026 15:45:09 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id CC96A43E7D; Wed, 2 Sep 2026 19:45:06 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D48EE1F00A3A; Wed, 2 Sep 2026 19:45:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788378306; bh=zrXu7dhERiW+wXiBbdy71b9VStVhzZds0WPzZYsva5E=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Feun9WvJT9a7UL/Z3VAZGMW7JuOdQLn2FYDx4mtf1ug/hVOMr4WLZXtDG1RlqDkP8 HE6+6mCV6vg9s5SOlaDbqWcSmJyte2SDP/as0d+Uzj3u16p88X6DtoVPJXyztw4RXO E7V0DDwNzNf6Hpkl/vU/X6ZHG2XIalKJhqeWrqE1NPaB4hthI8aNJ/Nr+ucvUMq4Fz N1eAsKhhUfknmUCq0LNDtbwWCI6xaiTYwIkq9oOvW/MYBCJE8duKg257LOnJO8VWwN IiVribX7eL4J7NL5+LN6qXxTJBvLZYhlp7kfGd8uGoPmSihsN3fKoD9GOCQMb3S7/n xgJgFiZ1BStZg== 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 v2 10/11] file-posix: reject a zone append past the device capacity Date: Wed, 2 Sep 2026 21:44:21 +0200 Message-ID: <20260902194423.759355-11-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260902194423.759355-1-cassel@kernel.org> References: <20260902194423.759355-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: 1788378386651154100 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") Reviewed-by: Damien Le Moal Signed-off-by: Niklas Cassel --- 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 20:50:33 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=1788378408; cv=none; d=zohomail.com; s=zohoarc; b=eM9Hw1aLCfG9gDFu/mwjXfEmrPl/D4Imx9gxyRKfb8sD5vuwASKaUqCXoAsVP1ILGpbAtnU5f/V8BgIOpUdmMCJZGy+PDMDPbpV+lumozvto8G7gE8H522RGO42eaCZXPakHjrTqPHNKVMRyTK3NvTIsgby4J2pTl1JMalAsxuA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788378408; 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=ftPopcfHae1aDSaoCzebEkqZIeJfOQJs19QFUP36+xI=; b=WxsVpO2iZXZKvOZoz4Lr7rby1oTVvlYtJbqun7tjn1TbTMqrfgjM6C8uSJW1DGljeeJhPvjG+adJPjHIYAZhjmWsQ4hoHQ83iFhdE68CB3+PL40aYQKUCgbt16Er369t+WGyUt+UE+9tI5a4IIn+1JBX+DllGelDQs6TdBsEyNI= 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 1788378408110514.0013624923522; Wed, 2 Sep 2026 12:46:48 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x1qtX-0000bK-L2; Wed, 02 Sep 2026 15:45: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 1x1qtU-0000Yk-6S; Wed, 02 Sep 2026 15:45:13 -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 1x1qtS-0006F2-HH; Wed, 02 Sep 2026 15:45:11 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by tor.source.kernel.org (Postfix) with ESMTP id 98F1F600D4; Wed, 2 Sep 2026 19:45:09 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 477D61F000E9; Wed, 2 Sep 2026 19:45:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788378309; bh=ftPopcfHae1aDSaoCzebEkqZIeJfOQJs19QFUP36+xI=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=MmPVBYE29e+CKZEzJt8GCQJLmrxVU7Oa/73iBsf46qrEjQ38QQMofkNmamfLhNRmV ObwYxj6YR0p7nvVusUG4/qlgi6NERfYp9mcHbbqL0fEAkt+xSII180RGRXmrwDuRre 9QS+6KQwsNnzdZ+G/UJnA9ow9F1fFf/RgRh9XENQe7+izjBxdVXEMAAUkNDc40xDxY KcHayCK1VsOuPw+qe/cXrkmBUZQi+e6LiWlyF/wOOJcUl6DNJXMNXNftA3K+6kYFCp 3u1mV9Ih2Sui4EJoRlmnysuDT+2kB4odKaekwB4XdzJkQShZFwUj1M+S5ZDekgQwk5 AVH3YWvZKh9pA== From: Niklas Cassel To: Stefan Hajnoczi , Kevin Wolf , Hanna Reitz , Fam Zheng Cc: Sam Li , Damien Le Moal , Niklas Cassel , qemu-block@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v2 11/11] file-posix: reject a zone append to a full or conventional zone Date: Wed, 2 Sep 2026 21:44:22 +0200 Message-ID: <20260902194423.759355-12-cassel@kernel.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260902194423.759355-1-cassel@kernel.org> References: <20260902194423.759355-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: 1788378411060154100 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 --- block/file-posix.c | 27 +++++++++++++++++++++++++-- block/io.c | 9 +++++++++ include/block/block-io.h | 6 ++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/block/file-posix.c b/block/file-posix.c index 85d735c079..57ba8dde64 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -2565,8 +2565,31 @@ 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]; + + /* + * 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 (bdrv_zone_is_full(bs, index)) { + 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 diff --git a/block/io.c b/block/io.c index 705dc73d76..3574e15a55 100644 --- a/block/io.c +++ b/block/io.c @@ -3371,6 +3371,15 @@ out: return co.ret; } =20 +bool bdrv_zone_is_full(BlockDriverState *bs, uint32_t index) +{ + uint64_t zone_end =3D MIN((uint64_t)(index + 1) * bs->bl.zone_size, + (uint64_t)bs->total_sectors << BDRV_SECTOR_BIT= S); + IO_CODE(); + + return bs->wps->wp[index] >=3D zone_end; +} + void *qemu_blockalign(BlockDriverState *bs, size_t size) { IO_CODE(); diff --git a/include/block/block-io.h b/include/block/block-io.h index d34d846bb2..2a9505312a 100644 --- a/include/block/block-io.h +++ b/include/block/block-io.h @@ -126,6 +126,12 @@ int coroutine_fn GRAPH_RDLOCK bdrv_co_zone_append(Bloc= kDriverState *bs, int64_t *offset, QEMUIOVector *qiov, BdrvRequestFlags flags); +/* + * True when the write pointer of a zone has reached the end of the writab= le + * part of that zone, so that nothing more can be written to it until it is + * reset. The write pointer lock must be held when called. + */ +bool bdrv_zone_is_full(BlockDriverState *bs, uint32_t index); =20 bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs); =20 --=20 2.55.0