The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Horst Birthelmer <horst@birthelmer.de>
To: Amir Goldstein <amir73il@gmail.com>
Cc: Horst Birthelmer <horst@birthelmer.com>,
	 Miklos Szeredi <miklos@szeredi.hu>,
	Bernd Schubert <bschubert@ddn.com>,
	 Joanne Koong <joannelkoong@gmail.com>,
	Luis Henriques <luis@igalia.com>,
	linux-kernel@vger.kernel.org,  fuse-devel@lists.linux.dev,
	Horst Birthelmer <hbirthelmer@ddn.com>
Subject: Re: Re: [PATCH v7 4/4] fuse: add compound command for dentry revalidation
Date: Fri, 5 Jun 2026 10:09:58 +0200	[thread overview]
Message-ID: <aiKD5muCy6iLLnK3@fedora.fritz.box> (raw)
In-Reply-To: <CAOQ4uxh5OzWVVPqJMe2g_jGhXBKLGUgKcEXW-_ShKtfXuTt7bQ@mail.gmail.com>

On Fri, Jun 05, 2026 at 10:06:55AM +0200, Amir Goldstein wrote:
> On Thu, Jun 4, 2026 at 11:51 AM Horst Birthelmer <horst@birthelmer.com> wrote:
> >
> > From: Horst Birthelmer <hbirthelmer@ddn.com>
> >
> > During dentry revalidation the compound LOOKUP+GETATTR
> > will save a round trip to user space.
> >
> > Signed-off-by: Horst Birthelmer <hbirthelmer@ddn.com>
> > ---
> >  fs/fuse/dir.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 111 insertions(+), 2 deletions(-)
> >
> > diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
> > index b3406c33abd2..99800e8ca895 100644
> > --- a/fs/fuse/dir.c
> > +++ b/fs/fuse/dir.c
> > @@ -372,6 +372,101 @@ static void fuse_lookup_init(struct fuse_args *args, u64 nodeid,
> >         args->out_args[0].value = outarg;
> >  }
> >
> > +/*
> > + * Revalidate a dentry using a compound LOOKUP+GETATTR.  Saves a round
> > + * trip when both the entry and the attributes need refreshing.
> > + *
> > + * Returns 1 if valid, 0 if the dentry should be invalidated, or a
> > + * negative errno that the caller should propagate (only -ENOMEM /
> > + * -EINTR; other errors are mapped to invalidate).
> > + */
> > +static int fuse_dentry_revalidate_compound(struct inode *dir,
> > +                                          const struct qstr *name,
> > +                                          struct dentry *entry,
> > +                                          struct inode *inode,
> > +                                          struct fuse_mount *fm,
> > +                                          u64 attr_version)
> > +{
> > +       struct fuse_entry_out lookup_out = {};
> > +       struct fuse_attr_out getattr_out = {};
> > +       struct fuse_getattr_in getattr_in = {};
> > +       struct fuse_args lookup_args = {};
> > +       struct fuse_args getattr_args = {};
> > +       struct fuse_forget_link *forget;
> > +       int lookup_err = 0, getattr_err = 0;
> > +       struct fuse_compound_op ops[2] = {
> > +               { .arg = &lookup_args,  .error = &lookup_err,
> > +                 .dep_index = FUSE_COMPOUND_NO_DEP },
> > +               { .arg = &getattr_args, .error = &getattr_err,
> > +                 .dep_index = 0 /* nodeid comes from lookup */ },
> > +       };
> > +       struct fuse_inode *fi;
> > +       int ret;
> > +
> > +       forget = fuse_alloc_forget();
> > +       if (!forget)
> > +               return -ENOMEM;
> > +
> > +       fuse_lookup_init(&lookup_args, get_node_id(dir), name, &lookup_out);
> > +       /* nodeid is filled from the lookup result before getattr is sent */
> > +       fuse_getattr_args_fill(&getattr_args, 0, &getattr_in, &getattr_out);
> > +
> > +       ret = fuse_compound_send(fm, ops, 2);
> > +       if (ret == -ENOMEM || ret == -EINTR)
> > +               goto out;
> > +       /*
> > +        * The non-compound revalidate path propagates -ENOMEM / -EINTR
> > +        * from the lookup to VFS instead of treating them as "invalidate
> > +        * this dentry".  Keep that behaviour when the lookup ran inside
> > +        * a compound: surface the per-subop error to the caller.
> > +        */
> > +       if (lookup_err == -ENOMEM || lookup_err == -EINTR) {
> > +               ret = lookup_err;
> > +               goto out;
> > +       }
> > +       if (ret < 0 || lookup_err || !lookup_out.nodeid) {
> > +               ret = 0;
> > +               goto out;
> > +       }
> > +
> > +       fi = get_fuse_inode(inode);
> > +       if (lookup_out.nodeid != get_node_id(inode) ||
> > +           (bool)IS_AUTOMOUNT(inode) != (bool)(lookup_out.attr.flags & FUSE_ATTR_SUBMOUNT)) {
> > +               fuse_queue_forget(fm->fc, forget, lookup_out.nodeid, 1);
> > +               forget = NULL;
> > +               ret = 0;
> > +               goto out;
> > +       }
> > +
> > +       spin_lock(&fi->lock);
> > +       fi->nlookup++;
> > +       spin_unlock(&fi->lock);
> > +
> > +       if (fuse_invalid_attr(&lookup_out.attr) ||
> > +           fuse_stale_inode(inode, lookup_out.generation, &lookup_out.attr)) {
> > +               ret = 0;
> > +               goto out;
> > +       }
> > +
> > +       forget_all_cached_acls(inode);
> > +
> > +       if (!getattr_err && !fuse_invalid_attr(&getattr_out.attr))
> > +               fuse_change_attributes(inode, &getattr_out.attr, NULL,
> > +                                      ATTR_TIMEOUT(&getattr_out),
> > +                                      attr_version);
> > +       else
> > +               fuse_change_attributes(inode, &lookup_out.attr, NULL,
> > +                                      ATTR_TIMEOUT(&lookup_out),
> > +                                      attr_version);
> > +
> > +       fuse_change_entry_timeout(entry, &lookup_out);
> > +       ret = 1;
> > +
> > +out:
> > +       kfree(forget);
> > +       return ret;
> > +}
> > +
> 
> That's duplicating a lot of subtle code.
> I think this calls for some helpers.

OK ... this was a new one (compound I mean), and I valued the compactness of the patch more
than the possible code duplication. You're probably right ...

> 
> Thanks,
> Amir.

  reply	other threads:[~2026-06-05  8:16 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-04  9:45 [PATCH v7 0/4] fuse: compound commands Horst Birthelmer
2026-06-04  9:45 ` [PATCH v7 1/4] fuse: add compound command to combine multiple requests Horst Birthelmer
2026-06-05  7:41   ` Amir Goldstein
2026-06-05  8:03     ` Horst Birthelmer
2026-06-06 17:30     ` Horst Birthelmer
2026-06-04  9:45 ` [PATCH v7 2/4] fuse: create helper functions for filling in fuse args for open and getattr Horst Birthelmer
2026-06-05  7:42   ` Amir Goldstein
2026-06-04  9:45 ` [PATCH v7 3/4] fuse: add an implementation of open+getattr Horst Birthelmer
2026-06-05  7:50   ` Amir Goldstein
2026-06-04  9:45 ` [PATCH v7 4/4] fuse: add compound command for dentry revalidation Horst Birthelmer
2026-06-05  8:06   ` Amir Goldstein
2026-06-05  8:09     ` Horst Birthelmer [this message]
2026-06-05  8:12 ` [PATCH v7 0/4] fuse: compound commands Amir Goldstein
2026-06-05  8:49   ` Horst Birthelmer
2026-06-05  9:15     ` Amir Goldstein
2026-06-05  9:28       ` Horst Birthelmer
2026-06-05 10:49     ` Bernd Schubert
2026-06-05 11:26       ` Horst Birthelmer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aiKD5muCy6iLLnK3@fedora.fritz.box \
    --to=horst@birthelmer.de \
    --cc=amir73il@gmail.com \
    --cc=bschubert@ddn.com \
    --cc=fuse-devel@lists.linux.dev \
    --cc=hbirthelmer@ddn.com \
    --cc=horst@birthelmer.com \
    --cc=joannelkoong@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luis@igalia.com \
    --cc=miklos@szeredi.hu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox