@samitouri / QOSamiQemu / commits / d1664a4058

block/export/fuse: set FUSE_DIRECT_IO_ALLOW_MMAP flag to fix regression

Commit 8599559580 ("fuse: Set direct_io and parallel_direct_writes") broke use cases that require mmap() with MAP_SHARED on the export. In particular, swtpm_setup using its 'file://' protocol requires this. From the kernel documentation [0]: > To allow shared mmap, the FUSE_DIRECT_IO_ALLOW_MMAP flag may be > enabled in the FUSE_INIT reply. Set the FUSE_DIRECT_IO_ALLOW_MMAP flag to restore compatibility with users requiring shared mmap. The FUSE_INIT_EXT flag needs to be set for the flags2 member to have an effect. [0]: https://www.kernel.org/doc/html/next/filesystems/fuse/fuse-io.html Cc: qemu-stable@nongnu.org Fixes: 8599559580 ("fuse: Set direct_io and parallel_direct_writes") Signed-off-by: Fiona Ebner <f.ebner@proxmox.com> Message-ID: <20260506145424.10249-3-f.ebner@proxmox.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>

Fiona Ebner committed May 6, 2026 at 16:49 UTC d1664a4058b2b4285d281d32c81ef646f78e7d9a
1 file changed +11 -2
block/export/fuse.c
+11 -2
@@ -856,7 +856,8 @@ static ssize_t coroutine_fn GRAPH_RDLOCK
856 fuse_co_init(FuseExport *exp, struct fuse_init_out *out,
857 const struct fuse_init_in *in)
858 {
859 - const uint32_t supported_flags = FUSE_ASYNC_READ | FUSE_ASYNC_DIO;
859 + uint32_t supported_flags = FUSE_ASYNC_READ | FUSE_ASYNC_DIO;
860 + uint32_t flags2 = 0;
861
862 if (in->major != 7) {
863 error_report("FUSE major version mismatch: We have 7, but kernel has %"
@@ -871,13 +872,21 @@ fuse_co_init(FuseExport *exp, struct fuse_init_out *out,
872 return -EINVAL;
873 }
874
875 + if (!using_old_fuse_init_in(in)) {
876 + /* The flags2 flags must be shifted down by 32 bits. */
877 + const uint32_t supported_flags2 = FUSE_DIRECT_IO_ALLOW_MMAP >> 32;
878 + /* flags2 is only considered if FUSE_INIT_EXT is set. */
879 + supported_flags = supported_flags | FUSE_INIT_EXT;
880 + flags2 = in->flags2 & supported_flags2;
881 + }
882 +
883 *out = (struct fuse_init_out) {
884 .major = 7,
885 .minor = MIN(FUSE_KERNEL_MINOR_VERSION, in->minor),
886 .max_readahead = in->max_readahead,
887 .max_write = FUSE_MAX_WRITE_BYTES,
888 .flags = in->flags & supported_flags,
880 - .flags2 = 0,
889 + .flags2 = flags2,
890
891 /* libfuse maximum: 2^16 - 1 */
892 .max_background = UINT16_MAX,