On 08.05.26 15:06, Hanna Czenczek wrote:
On 08.05.26 13:55, Fiona Ebner wrote:
Dear maintainers,
Am 10.03.26 um 6:37 PM schrieb Kevin Wolf:
From: Hanna Czenczek <[email protected]>
Manually read requests from the /dev/fuse FD and process them, without
using libfuse. This allows us to safely add parallel request
processing
in coroutines later, without having to worry about libfuse internals.
(Technically, we already have exactly that problem with
read_from_fuse_export()/read_from_fuse_fd() nesting.)
We will continue to use libfuse for mounting the filesystem;
fusermount3
is a effectively a helper program of libfuse, so it should know best
how
to interact with it. (Doing it manually without libfuse, while doable,
is a bit of a pain, and it is not clear to me how stable the "protocol"
actually is.)
Take this opportunity of quite a major rewrite to update the Copyright
line with corrected information that has surfaced in the meantime.
a colleague ran into another issue with a fuse export, this time in
combination with virt-fw-vars and bisecting points to this patch.
Before commit a94a1d7699 ("fuse: Manually process requests (without
libfuse)") the reproducer [0] completes successfully, after that
commit it hangs at [1]. The issue is still present with current
master. I can dig into the details next week.
On my system, virt-fw-vars opens the file with O_TRUNC (after “INFO:
writing raw edk2 varstore...”). It then tries to write to the file,
but this returns a short write because the export is not marked as
growable, and for some reason, the write is infinitely retried instead
of aborting on ret=0 (which should indicate ENOSPC for writes).
Using growable=true makes it work. (For me :))
For some reason, before said commit, libfuse just did not pass that
truncate on. I’ll look into why exactly, but so far I would say the
FUSE export behavior is as I would expect it.
Ah, I see. libfuse sets FUSE_CAP_ATOMIC_O_TRUNC, which has O_TRUNC be
passed on as an open option, but the old export code just ignored all
open options.
The new code does not set that option, so O_TRUNC is executed as an
explicit truncate by the kernel, which then *is* executed.
I’m not entirely sure how we should handle it. There is a case to be
made that with growable=off, it may make sense to ignore O_TRUNC (which
requires turning on FUSE_CAP_ATOMIC_O_TRUNC again and then continue to
ignore it). But on the other hand, O_TRUNC is O_TRUNC, and growable=off
does not explicitly mean “please behave as much as a block device as
possible”.
What do you suggest?
Hanna