From: Luis Henriques <luis@igalia.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: Bernd Schubert <bernd@bsbernd.com>,
Laura Promberger <laura.promberger@cern.ch>,
Dave Chinner <david@fromorbit.com>,
Matt Harvey <mharvey@jumptrading.com>,
linux-fsdevel@vger.kernel.org, kernel-dev@igalia.com,
linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH v5 1/2] fuse: new work queue to periodically invalidate expired dentries
Date: Thu, 04 Sep 2025 15:00:12 +0100 [thread overview]
Message-ID: <87y0qul3mb.fsf@wotan.olymp> (raw)
In-Reply-To: <CAJfpegtfeCJgzSLOYABTaZ7Hec6JDMHpQtxDzg61jAPJcRZQZA@mail.gmail.com> (Miklos Szeredi's message of "Thu, 4 Sep 2025 12:20:46 +0200")
Hi Miklos,
On Thu, Sep 04 2025, Miklos Szeredi wrote:
> On Thu, 28 Aug 2025 at 18:30, Luis Henriques <luis@igalia.com> wrote:
>
>> +#define HASH_BITS 12
>
> Definitely too large. My gut feeling gives 5, but it obviously
> depends on a lot of factors.
Right, to be honest I didn't spent a lot of time thinking about the
correct value for this constant. But sure, 5 seems to be much more
reasonable.
>> + schedule_delayed_work(&dentry_tree_work,
>> + secs_to_jiffies(num));
>
> secs_to_jiffues() doesn't check overflow. Perhaps simplest fix would
> be to constrain parameter to unsigned short.
Sounds good, thanks.
>> +MODULE_PARM_DESC(inval_wq,
>> + "Dentries invalidation work queue period in secs (>= 5).");
>
> __stringify(FUSE_DENTRY_INVAL_FREQ_MIN)
>
>> + if (!inval_wq && RB_EMPTY_NODE(&fd->node))
>> + return;
>
> inval_wq can change to zero, which shouldn't prevent removing from the rbtree.
Maybe I didn't understood your comment, but isn't that what's happening
here? If the 'fd' is in a tree, it will be removed, independently of the
'inval_wq' value.
>> +static void fuse_dentry_tree_work(struct work_struct *work)
>> +{
>> + struct fuse_dentry *fd;
>> + struct rb_node *node;
>> + int i;
>> +
>> + for (i = 0; i < HASH_SIZE; i++) {
>> + spin_lock(&dentry_hash[i].lock);
>> + node = rb_first(&dentry_hash[i].tree);
>> + while (node && !need_resched()) {
>
> Wrong place.
>
>> + fd = rb_entry(node, struct fuse_dentry, node);
>> + if (time_after64(get_jiffies_64(), fd->time)) {
>> + rb_erase(&fd->node, &dentry_hash[i].tree);
>> + RB_CLEAR_NODE(&fd->node);
>> + spin_unlock(&dentry_hash[i].lock);
>
> cond_resched() here instead.
/me slaps himself.
>> + d_invalidate(fd->dentry);
>
> Okay, so I understand the reasoning: the validity timeout for the
> dentry expired, hence it's invalid. The problem is, this is not quite
> right. The validity timeout says "this dentry is assumed valid for
> this period", it doesn't say the dentry is invalid after the timeout.
>
> Doing d_invalidate() means we "know the dentry is invalid", which will
> get it off the hash tables, giving it a "(deleted)" tag in proc
> strings, etc. This would be wrong.
Understood. Thanks a lot for taking the time to explain it. This makes
it clear that using d_invalidate() here is incorrect, of course.
> What we want here is just get rid of *unused* dentries, which don't
> have any reference. Referenced ones will get revalidated with
> ->d_revalidate() and if one turns out to be actually invalid, it will
> then be invalidated with d_invalidate(), otherwise the timeout will
> just be reset.
>
> There doesn't seem to be a function that does this, so new
> infrastructure will need to be added to fs/dcache.c. Exporting
> shrink_dentry_list() and to_shrink_list() would suffice, but I wonder
> if the helpers should be a little higher level.
OK, I see how the to_shrink_list() and shrink_dentry_list() pair could
easily be used here. This would even remove the need to do the
unlock/lock in the loop.
(By the way, I considered using mutexes here instead. Do you have any
thoughts on this?)
What I don't understand in your comment is where you suggest these helpers
could be in a higher level. Could you elaborate on what exactly you have
in mind?
>> +void fuse_dentry_tree_cleanup(void)
>> +{
>> + struct rb_node *n;
>> + int i;
>> +
>> + inval_wq = 0;
>> + cancel_delayed_work_sync(&dentry_tree_work);
>> +
>> + for (i = 0; i < HASH_SIZE; i++) {
>
> If we have anything in there at module remove, then something is
> horribly broken. A WARN_ON definitely suffices here.
>
>> --- a/fs/fuse/fuse_i.h
>> +++ b/fs/fuse/fuse_i.h
>> @@ -54,6 +54,12 @@
>> /** Frequency (in jiffies) of request timeout checks, if opted into */
>> extern const unsigned long fuse_timeout_timer_freq;
>>
>> +/*
>> + * Dentries invalidation workqueue period, in seconds. It shall be >= 5
>
> If we have a definition of this constant, please refer to that
> definition here too.
>
>> @@ -2045,6 +2045,10 @@ void fuse_conn_destroy(struct fuse_mount *fm)
>>
>> fuse_abort_conn(fc);
>> fuse_wait_aborted(fc);
>> + /*
>> + * XXX prune dentries:
>> + * fuse_dentry_tree_prune(fc);
>> + */
>
> No need.
Yeah, I wasn't totally sure this would really be required here.
And again, thanks a lot for your review, Miklos!
Cheers,
--
Luís
next prev parent reply other threads:[~2025-09-04 14:00 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-28 16:29 [RFC PATCH v5 0/2] fuse: work queues to invalided dentries Luis Henriques
2025-08-28 16:29 ` [RFC PATCH v5 1/2] fuse: new work queue to periodically invalidate expired dentries Luis Henriques
2025-09-04 10:20 ` Miklos Szeredi
2025-09-04 14:00 ` Luis Henriques [this message]
2025-09-04 15:12 ` Miklos Szeredi
2025-09-04 15:30 ` Luis Henriques
2025-08-28 16:29 ` [RFC PATCH v5 2/2] fuse: new work queue to invalidate dentries from old epochs Luis Henriques
2025-09-04 10:35 ` Miklos Szeredi
2025-09-04 14:11 ` Luis Henriques
2025-09-04 14:38 ` Miklos Szeredi
2025-09-04 15:21 ` Luis Henriques
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=87y0qul3mb.fsf@wotan.olymp \
--to=luis@igalia.com \
--cc=bernd@bsbernd.com \
--cc=david@fromorbit.com \
--cc=kernel-dev@igalia.com \
--cc=laura.promberger@cern.ch \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mharvey@jumptrading.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.