From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id E373C1FF141 for ; Tue, 05 May 2026 15:11:20 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 069462287; Tue, 5 May 2026 15:11:17 +0200 (CEST) From: Fiona Ebner To: pve-devel@lists.proxmox.com Subject: [PATCH qemu 3/3] add fix for regression when using fuse export for swtpm Date: Tue, 5 May 2026 15:10:17 +0200 Message-ID: <20260505131035.743948-4-f.ebner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260505131035.743948-1-f.ebner@proxmox.com> References: <20260505131035.743948-1-f.ebner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1777986533339 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.009 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: 6MG6SIW22PB3SX5YXOXPYRNKVTPGVTHD X-Message-ID-Hash: 6MG6SIW22PB3SX5YXOXPYRNKVTPGVTHD X-MailFrom: f.ebner@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The swtpm_setup binary will fail accessing a FUSE export from qemu-storage-daemon since QEMU commit 8599559580 ("fuse: Set direct_io and parallel_direct_writes"). It uses mmap() with MAP_SHARED, which fails fails when direct IO is used, but the FUSE_DIRECT_IO_ALLOW_MMAP flag is not. This is documented behavior [0]. Enable the flag if the kernel supports it to fix the regression. Discussion upstream [1]. [0]: https://www.kernel.org/doc/html/next/filesystems/fuse/fuse-io.html [1]: https://lore.kernel.org/qemu-devel/e86b82e4-a85d-46d2-bb8f-4e0f59e49a44@proxmox.com/ Signed-off-by: Fiona Ebner --- ...e-fix-regression-when-mmap-ing-expor.patch | 94 +++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 95 insertions(+) create mode 100644 debian/patches/extra/0012-block-export-fuse-fix-regression-when-mmap-ing-expor.patch diff --git a/debian/patches/extra/0012-block-export-fuse-fix-regression-when-mmap-ing-expor.patch b/debian/patches/extra/0012-block-export-fuse-fix-regression-when-mmap-ing-expor.patch new file mode 100644 index 0000000000..71df0416de --- /dev/null +++ b/debian/patches/extra/0012-block-export-fuse-fix-regression-when-mmap-ing-expor.patch @@ -0,0 +1,94 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +Date: Tue, 5 May 2026 13:04:29 +0200 +Subject: [PATCH] block/export/fuse: fix regression when mmap()-ing export with + MAP_SHARED + +The swtpm_setup binary will fail accessing a FUSE export from +qemu-storage-daemon since commit 8599559580 ("fuse: Set direct_io and +parallel_direct_writes"). It uses mmap() with MAP_SHARED, which fails +fails when direct IO is used, but the FUSE_DIRECT_IO_ALLOW_MMAP flag +is not. This is documented behavior [0]. Enable the flag if the kernel +supports it to fix the regression. + +The FUSE_INIT_EXT flag needs to be set to be able to use the flags2 +argument. + +This patch bumps the required minimal protocol version to 7.36 for +availablity of the FUSE_INIT_EXT flag, which is available since kernel +5.17. A proper upstream submission should try to avoid this. +Discussion upstream [1]. + +[0]: https://www.kernel.org/doc/html/next/filesystems/fuse/fuse-io.html +[1]: https://lore.kernel.org/qemu-devel/e86b82e4-a85d-46d2-bb8f-4e0f59e49a44@proxmox.com/ + +Fixes: 8599559580 ("fuse: Set direct_io and parallel_direct_writes") +Signed-off-by: Fiona Ebner +--- + block/export/fuse.c | 27 ++++++++------------------- + 1 file changed, 8 insertions(+), 19 deletions(-) + +diff --git a/block/export/fuse.c b/block/export/fuse.c +index a2a478d293..ef381fd844 100644 +--- a/block/export/fuse.c ++++ b/block/export/fuse.c +@@ -51,23 +51,11 @@ + #define FUSE_MAX_READ_BYTES (MIN(BDRV_REQUEST_MAX_BYTES, 1 * 1024 * 1024)) + #define FUSE_MAX_WRITE_BYTES (64 * 1024) + +-/* +- * fuse_init_in structure before 7.36. We don't need the flags2 field added +- * there, so we can work with the smaller older structure to stay compatible +- * with older kernels. +- */ +-struct fuse_init_in_compat { +- uint32_t major; +- uint32_t minor; +- uint32_t max_readahead; +- uint32_t flags; +-}; +- + typedef struct FuseRequestInHeader { + struct fuse_in_header common; + /* All supported requests */ + union { +- struct fuse_init_in_compat init; ++ struct fuse_init_in init; + struct fuse_open_in open; + struct fuse_setattr_in setattr; + struct fuse_read_in read; +@@ -826,9 +814,10 @@ static bool is_regular_file(const char *path, Error **errp) + */ + static ssize_t coroutine_fn GRAPH_RDLOCK + fuse_co_init(FuseExport *exp, struct fuse_init_out *out, +- const struct fuse_init_in_compat *in) ++ const struct fuse_init_in *in) + { +- const uint32_t supported_flags = FUSE_ASYNC_READ | FUSE_ASYNC_DIO; ++ const uint32_t supported_flags = FUSE_ASYNC_READ | FUSE_ASYNC_DIO | FUSE_INIT_EXT; ++ const uint32_t supported_flags2 = (FUSE_DIRECT_IO_ALLOW_MMAP >> 32); + + if (in->major != 7) { + error_report("FUSE major version mismatch: We have 7, but kernel has %" +@@ -836,9 +825,9 @@ fuse_co_init(FuseExport *exp, struct fuse_init_out *out, + return -EINVAL; + } + +- /* 2007's 7.9 added fuse_attr.blksize; working around that would be hard */ +- if (in->minor < 9) { +- error_report("FUSE minor version too old: 9 required, but kernel has %" ++ /* Kernel 5.17's 7.36 protocol version added FUSE_INIT_EXT */ ++ if (in->minor < 36) { ++ error_report("FUSE minor version too old: 36 required, but kernel has %" + PRIu32, in->minor); + return -EINVAL; + } +@@ -849,7 +838,7 @@ fuse_co_init(FuseExport *exp, struct fuse_init_out *out, + .max_readahead = in->max_readahead, + .max_write = FUSE_MAX_WRITE_BYTES, + .flags = in->flags & supported_flags, +- .flags2 = 0, ++ .flags2 = in->flags2 & supported_flags2, + + /* libfuse maximum: 2^16 - 1 */ + .max_background = UINT16_MAX, diff --git a/debian/patches/series b/debian/patches/series index 8553c8ed8c..39da6dff13 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -9,6 +9,7 @@ extra/0008-qcow2-Fix-corruption-on-discard-during-write-with-CO.patch extra/0009-target-i386-fix-strList-leak-in-x86_cpu_get_unavaila.patch extra/0010-target-i386-fix-missing-PF_INSTR-in-SIGSEGV-context.patch extra/0011-migration-vmstate_save_state_v-fix-double-error_setg.patch +extra/0012-block-export-fuse-fix-regression-when-mmap-ing-expor.patch bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch -- 2.47.3