On Wed, Jul 23, 2025 at 8:30 PM Paul Lawrence <paullawrence@xxxxxxxxxx> wrote: > > > FUSE_CREATE already returns two out args. > > How were you planning to extend it? > > Excellent point. However, FUSE_CREATE (and FUSE_TMPFILE) already has > fuse_open_out as the second argument, so the backing_id can be passed > in there. Does that sound acceptable? I'll admit that at first this > seemed clunky to me, but the more I think about it, the more natural > it seems - create is really an open, so it follows that paradigm, and > the new paradigm is used only for FUSE_LOOKUP. > Yes, you are right. FUSE_CREATE already has backing_id anyway. > FUSE_READDIRPLUS is harder, it seems to me. We would need to break ABI > compatibility - I can't see any sane alternative. A clean way would be > to have a FUSE_READDIR_PASSTHROUGH opcode. This implies that there's a > flag FUSE_PASSTHROUGH_MASK covering all of this new functionality > which would also enable this new opcode. (It could, alternatively, > change the behavior of FUSE_READDIRPLUS but I suspect no one is going > to like that idea.) Let's leave readdirplus for the very end. It's not very important for the first version IMO. > > Does this seem reasonable? Yes. sounds good to me. Thanks, Amir. > > Thanks, > Paul > > > > > On Wed, Jul 23, 2025 at 9:53 AM Amir Goldstein <amir73il@xxxxxxxxx> wrote: > > > > On Tue, Jul 22, 2025 at 11:13 PM Paul Lawrence <paullawrence@xxxxxxxxxx> wrote: > > > > > > I spent a little time with these patches. I wrote my own to set the > > > backing file at lookup time by adding an optional second out struct. > > > > FUSE_CREATE already returns two out args. > > How were you planning to extend it? > > > > > Is there a reason we should not do this? It seems the most natural > > > solution. > > > > > > After a while, I began to wonder if what I was planning was actually > > > the same as your vision. I decided to jot down my thoughts to see if > > > you agree with them. Also I was confused as to why you were adding the > > > ability to set backing files to GETATTR. > > > > It is a demo. It demonstrates that passthrough can be set up sooner than > > open time. It was not my intention to keep it this way. > > > > > So here are my notes. > > > > > > Design of fuse passthrough for all operations > > > > > > Goal: > > > > > > When a fuse filesystem implements a stacking filesystem over an > > > underlying file system, and a significant fraction of the calls will > > > simply be passed to the underlying file system, provide a mechanism to > > > pass those calls through without going to user space. This is > > > primarily to enhance performance, though it might simplify the daemon > > > somewhat too. > > > > > > Current state: > > > > > > Currently passthrough allows a backing file to be set at file open > > > time. If a backing file is set, all read/write operations will be > > > forwarded to the backing file. > > > > > > Design: > > > > > > Add ability to set backing file on the found inode in response to a > > > positive lookup. This file might be opened with O_PATH for performance > > > reasons. The lookup api would be modified to have an optional second > > > out struct that contains the backing file id. Note that we will use > > > the backing file ioctl to create this id to remove any security > > > concerns. > > > > > > The ioctl will also take a 64-bit integer to define which operations > > > will be passed through, the operations mask. This will have one bit > > > for each of the existing FUSE_OPERATIONS, at least the ones that act > > > on inodes/files. > > > > > > Then when fuse fs is considering calling out to the daemon with an > > > opcode, fuse fs will check if the inode has a backing file and mask. > > > If it does, and the specific opcode bit is set, fuse fs will instead > > > call out to a kernel function in backing.c that can perform that > > > operation on the backing file correctly. > > > > > > Details: > > > > > > Question: Will it be possible to change the mask/backing file after > > > the initial setting? My feeling is that it might well be useful to be > > > able to set the mask, the file not so much. Situations would be (for > > > example) a caching file system that turns off read forwarding once the > > > whole file is downloaded. > > > > > > > Generally, enabling passthrough from a point in time until the end of > > inode lifetime is easier than turning it off, but also there are many > > dependencies between passthrough ops and inode state so it will > > require a lot of care to enable *some* operations mid inode lifetime. > > > > > FUSE_OPEN will, if the backing file has been set, reopen it as a file > > > (not a path) if needed. This is whether or not FUSE_OPEN is passed > > > through. > > > > > > If FUSE_OPEN is passed through, user space will not get the chance to > > > assign a file handle ID to the opened file. It will still be possible > > > to pass FUSE_READ etc to the daemon - the daemon will still have the > > > node id and be able to read data based on that. > > > > > > > Not sure I understand what you mean, but we do support per file opt-out of > > passthrough with FOPEN_DIRECT_IO even when the inode is already > > set up for passthrough. > > > > > FUSE_LOOKUP can return a 0 node id, but only if *all* operations on > > > that node as marked as passthrough. > > > > Not sure why this is but I will be open to understanding. > > Will need an elaborate design of the inode lifetime in this case. > > > > > > > > Suggestion: During FUSE_LOOKUP, if FUSE_GETATTR is set in the mask, > > > ignore the passed in attributes and read them from the backing file. > > > > My patches already implement that when GETATTR is in the mask. > > > > > > > > Random, non-exhastive list of considerations: > > > > > > FUSE_FORGET can only be marked passthrough if the node id is 0. > > > > > > FUSE_CREATE returns a new node id and file handle. It would need the > > > ability to set backing files. > > > > > > If FUSE_LOOKUP is marked for passthrough, then looked up inodes will > > > be prepopulated with a backing O_PATH file and a mask will all bits > > > set. > > > > > > FUSE_RENAME takes two nodes and names, and moves one to the other. If > > > one is passthrough and one is not, there is no obvious way of > > > performing a rename. Either fall back to copy/delete or return EXDEV > > > > Good question. > > > > My patches were meant to provide you the basic infrastructure to enter > > this playground and show that you do not need backing dentry/inode > > beyond what is already available. > > > > I hope this is enough for you to start experimenting and sending RFC patches > > with design doc! > > > > Thanks, > > Amir.