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 --- fs/fuse/dir.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 2f89804b9ff3..cd6c92be7a2c 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(); -- 2.52.0