Re: [PATCH v7 1/6] fuse: decouple fuse_ring creation from ent registration
Bernd Schubert <[email protected]>
| Newsgroups | dev.linux.lists.fuse-devel |
|---|---|
| Message-ID | <[email protected]> |
On 8/20/26 18:16, Joanne Koong wrote: > On Thu, Aug 20, 2026 at 1:02 AM Baokun Li <[email protected]> wrote: >> >> Hi all, >> >> On 2026/8/20 04:05, Bernd Schubert wrote: >>> >>> On 8/19/26 19:56, Joanne Koong wrote: >>>> On Wed, Aug 19, 2026 at 4:35 AM Miklos Szeredi <[email protected]> wrote: >>>>> On Fri, 14 Aug 2026 at 21:00, Joanne Koong <[email protected]> wrote: >>>>>> Currently, the connection's fuse_ring is created lazily on the first >>>>>> FUSE_IO_URING_CMD_REGISTER command. A server registers entries from one >>>>>> thread per queue (one per CPU) and those threads issue their first >>>>>> REGISTER command concurrently. They then race to create the single >>>>>> per-connection fuse_ring, which required open-coded handling in >>>>>> fuse_uring_create() to detect and protect against concurrent creations. >>>>>> >>>>>> Decouple fuse_ring creation from ent registration and move it to >>>>>> FUSE_INIT reply processing after a server has negotiated and set >>>>>> FUSE_OVER_IO_URING. The ring is published before the connection is >>>>>> marked initialized. fuse_uring_register() no longer creates the ring and >>>>>> it instead uses the ring set up at init time. >>>>> I tested this with loraw (a "raw" loopback tester that doesn't use >>>>> libfuse) and it fails with >>>>> >>>>> root@kvm:~# ./loraw -u /mnt/fuse >>>>> loraw: loraw.c:1010: lo_start_uring: Assertion `!cqe->res' failed. >>>>> >>>>> cqe->res is -22 (EINVAL). >>>>> >>>>> Attaching the reproducer. To compile: >>>>> >>>>> cp $(KERNEL_TREE)/include/uapi/linux/fuse.h fuse_kernel.h >>>>> gcc loraw.c -oloraw -luring >>>>> >>>> Thanks for attaching the repro. >>>> >>>> This is happening because this patch uses the FUSE_OVER_IO_URING init >>>> reply as a signal that the ring should be created, but I missed that >>>> the FUSE_OVER_IO_URING reply is *optional*. >>>> >>>> Prior to this patch, there's two scenarios: >>>> a) server sets FUSE_OVER_IO_URING reply at init time - requests will >>>> automatically block until fuse-io-uring is completely set up >>>> b) server does not set FUSE_OVER_IO_URING but later sends uring >>>> register request - requests will continue along /dev/fuse path until >>>> fuse-io-uring is completely set up >>>> >>>> Libfuse sets FUSE_OVER_IO_URING in the reply, but the loraw.c server does not. >>>> >>>> I think the best way to fix this is to have the ring creation happen >>>> when the kernel receives the first io-uring command instead of at >>>> FUSE_INIT or at FUSE_IO_URING_CMD_REGISTER ent creation time, given >>>> that FUSE_IO_URING_ADD_QUEUE needs the ring to exist: >>> I don't think we should allow io-uring without FUSE_OVER_IO_URING and >>> I really thought that was disabled. >> >> I share Bernd's concern here. Allowing io-uring without >> FUSE_OVER_IO_URING means enabling a capability beyond what was >> negotiated. We should honor the negotiated feature set, and print >> the negotiated flags to dmesg at INIT time so issues like this are >> easy to spot. > > Not sure if you missed this reply [1], but will copy and paste it here: > > This is pre-existing behavior that's been there since the beginning > (kernel version 6.14). I don't think we can change this now, or > it'll break backwards compatibility, like Miklos's loraw program. > I think we need to discuss this. I had replied that the current accidental scheme we - deadlock (lock order), with bg_lock being one issue, but I bet there is more - module option bypass - bypass of what fuse-client/kernel announces I.e. if a fuse-server did implement the accidental scheme, it was broken anyway. If wanted to be paranoid, we would switch to FUSE_OVER_IO_URING2 flag and ignore FUSE_OVER_IO_URING. I hope you don't insist on allowing fuse-server to set flags that fuse-server doesn't even announce... Thanks, Bernd