Re: [RFC PATCH v3 6/8] fuse: implementation of lookup_handle+statx compound operation

Joanne Koong
2026-04-07T17:44:02Z

On Wed, Feb 25, 2026 at 3:25 AM Luis Henriques <luis@igalia.com> wrote:
>
> The implementation of lookup_handle+statx compound operation extends the
> lookup operation so that a file handle is be passed into the kernel. It
> also needs to include an extra inarg, so that the parent directory file
> handle can be sent to user-space. This extra inarg is added as an extension
> header to the request.
>
> By having a separate statx including in a compound operation allows the
> attr to be dropped from the lookup_handle request, simplifying the
> traditional FUSE lookup operation.
>
> Signed-off-by: Luis Henriques <luis@igalia.com>
> ---
> fs/fuse/dir.c | 294 +++++++++++++++++++++++++++++++++++---
> fs/fuse/fuse_i.h | 23 ++-
> fs/fuse/inode.c | 48 +++++--
> fs/fuse/readdir.c | 2 +-
> include/uapi/linux/fuse.h | 23 ++-
> 5 files changed, 355 insertions(+), 35 deletions(-)
>
> diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
> index 113583c4efb6..89e6176abe25 100644
> --- a/include/uapi/linux/fuse.h
> +++ b/include/uapi/linux/fuse.h
>
> enum fuse_opcode {
> @@ -671,6 +676,8 @@ enum fuse_opcode {
> */
> FUSE_COMPOUND = 54,
>
> + FUSE_LOOKUP_HANDLE = 55,
> +
> /* CUSE specific operations */
> CUSE_INIT = 4096,
>
> @@ -707,6 +714,20 @@ struct fuse_entry_out {
> struct fuse_attr attr;
> };
>
> +struct fuse_entry2_out {
> + uint64_t nodeid;
> + uint64_t generation;
> + uint64_t entry_valid;
> + uint32_t entry_valid_nsec;
> + uint32_t flags;
> + uint64_t spare;
> +};

Hi Luis,

Could you explain why we need a new struct fuse_entry2_out instead of
reusing struct fuse_entry_out? From what i see, the only differences
between them are that fuse_entry2_out drops attr_valid,
attr_valid_nsec, and struct fuse_attr. Is this done so that it saves
the ~100 bytes per lookup? Would it be cleaner from an abi perspective
to just reuse fuse_entry_out and ignore the attr fields if they're not
necessary? The reason I'm asking is because I'm looking at how you're
doing the lookup request reply to see if the fuse passthrough stuff
for metadata/directory operations can be combined with it. But I'm not
fully understanding why fuse_entry2_out is needed here.

I'm also a bit confused by why the compound with statx is needed here,
could you explain this part? I see the call to fuse_statx_to_attr()
after do_lookup_handle_statx(), but fuse_statx_to_attr() converts the
statx reply right back to a struct fuse_attr for inode setup, so if
FUSE_LOOKUP_HANDLE returned struct fuse_entry_out instead of struct
fuse_entry2_out, doesn't this solve the problem of needing to compound
it with a statx or getattr request? I also noticed that the statx part
uses FUSE_ROOT_ID as a workaround for the node id because the actual
nodeid isn't known yet, this seems like another sign that the
attributes stuff should just be part of the lookup response itself
rather than a separate operation?

Thanks,
Joanne

> +
> +struct fuse_file_handle {
> + uint16_t size;
> + uint8_t handle[];
> +};
> +
> struct fuse_forget_in {
> uint64_t nlookup;
> };