summaryrefslogtreecommitdiff
path: root/fs/fuse
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2026-01-14 15:53:39 +0100
committerChristian Brauner <brauner@kernel.org>2026-01-16 19:15:14 +0100
commit1e2c1af1beb395841743e240a59ab37edc9a7d33 (patch)
tree5b6bee79b87eb9fed11bae55914ab3bfd8d9a407 /fs/fuse
parentcb8d2bdcb8241b66ca4ac4868f20e12cd6881ebc (diff)
fuse: make sure dentry is evicted if stale
d_dispose_if_unused() may find the dentry with a positive refcount, in which case it won't be put on the dispose list even though it has already timed out. "Reinstall" the d_delete() callback, which was optimized out in fuse_dentry_settime(). This will result in the dentry being evicted as soon as the refcount hits zero. Fixes: ab84ad597386 ("fuse: new work queue to periodically invalidate expired dentries") Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Link: https://patch.msgid.link/20260114145344.468856-3-mszeredi@redhat.com Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/dir.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index ea90dd682bc3..c9922af79dfa 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -172,6 +172,10 @@ static void fuse_dentry_tree_work(struct work_struct *work)
if (time_after64(get_jiffies_64(), fd->time)) {
rb_erase(&fd->node, &dentry_hash[i].tree);
RB_CLEAR_NODE(&fd->node);
+ spin_lock(&fd->dentry->d_lock);
+ /* If dentry is still referenced, let next dput release it */
+ fd->dentry->d_flags |= DCACHE_OP_DELETE;
+ spin_unlock(&fd->dentry->d_lock);
d_dispose_if_unused(fd->dentry, &dispose);
spin_unlock(&dentry_hash[i].lock);
cond_resched();