On Mon, Feb 24, 2025 at 7:25 AM John Groves <John@xxxxxxxxxx> wrote: > > Miklos et. al.: > > Here are some specific questions related to the famfs port into fuse [1][2] > that I hope Miklos (and others) can give me feedback on soonish. > > This work is active and serious, although you haven't heard much from me > recently. I'm showing a famfs poster at Usenix FAST '25 this week [3]. > > I'm generally following the approach in [1] - in a famfs file system, > LOOKUP is followed by GET_FMAP to retrieve the famfs file/dax metadata. > It's tempting to merge the fmap into the LOOKUP reply, but this seems like > an optimization to consider once basic function is established. > > Q: Do you think it makes sense to make the famfs fmap an optional, > variable sized addition to the LOOKUP response? > > Whenever an fmap references a dax device that isn't already known to the > famfs/fuse kernel code, a GET_DAXDEV message is sent, with the reply > providing the info required to open teh daxdev. A file becomes available > when the fmap is complete and all referenced daxdevs are "opened". > > Q: Any heartburn here? > > When GET_FMAP is separate from LOOKUP, READDIRPLUS won't add value unless it > receives fmaps as part of the attributes (i.e. lookups) that come back in > its response - since a READDIRPLUS that gets 12 files will still need 12 > GET_FMAP messages/responses to be complete. Merging fmaps as optional, > variable-length components of the READDIRPLUS response buffers could > eventualy make sense, but a cleaner solution intially would seem to be > to disable READDIRPLUS in famfs. But... > Hi John, > * The libfuse/kernel ABI appears to allow low-level fuse servers that don't > support READDIRPLUS... > * But libfuse doesn't look at conn->want for the READDIRPLUS related > capabilities > * I have overridden that, but the kernel still sends the READDIRPLUS > messages. It's possible I'm doing something hinky, and I'll keep looking > for it. On the kernel side, FUSE_READDIR / FUSE_READDIRPLUS requests are sent in fuse_readdir_uncached(). I don't see anything there that skips sending readdir / readdirplus requests if the server doesn't have .readdir / .readdirplus implemented. For some request types (eg FUSE_RENAME2, FUSE_LINK, FUSE_FSYNCDIR, FUSE_CREATE, ...), we do track if a request type isn't implemented by the server and then skip sending that request in the future (for example, see fuse_tmpfile()). If we wanted to do this skipping for readdir as well, it'd probably look something like --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -870,6 +870,9 @@ struct fuse_conn { /* Is link not implemented by fs? */ unsigned int no_link:1; + /* Is readdir/readdirplus not implemented by fs? */ + unsigned int no_readdir:1; + /* Use io_uring for communication */ unsigned int io_uring; diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c index 17ce9636a2b1..176d6ce953e5 100644 --- a/fs/fuse/readdir.c +++ b/fs/fuse/readdir.c @@ -341,6 +341,9 @@ static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx) u64 attr_version = 0, evict_ctr = 0; bool locked; + if (fm->fc->no_readdir) + return -ENOSYS; + folio = folio_alloc(GFP_KERNEL, 0); if (!folio) return -ENOMEM; @@ -376,6 +379,8 @@ static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx) res = parse_dirfile(folio_address(folio), res, file, ctx); } + } else if (res == -ENOSYS) { + fm->fc->no_readdir = 1; } folio_put(folio); > * When I just return -ENOSYS to READDIRPLUS, things don't work well. Still > looking into this. > > Q: Do you know whether the current fuse kernel mod can handle a low-level > fuse server that doesn't support READDIRPLUS? This may be broken.