summaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2023-10-30 00:02:14 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2023-11-25 02:33:42 -0500
commit15220fbf187100e1cc1ad553b7d21633bdc27e76 (patch)
tree32413f7b3641d3eaea6f52ceb5f6056b34d60e76 /fs/dcache.c
parentcd9f84f35c2eaaf4da7e111021b604662326d8aa (diff)
downloadlinux-15220fbf187100e1cc1ad553b7d21633bdc27e76.tar.gz
linux-15220fbf187100e1cc1ad553b7d21633bdc27e76.tar.bz2
linux-15220fbf187100e1cc1ad553b7d21633bdc27e76.zip
fast_dput(): having ->d_delete() is not reason to delay refcount decrement
->d_delete() is a way for filesystem to tell that dentry is not worth keeping cached. It is not guaranteed to be called every time a dentry has refcount drop down to zero; it is not guaranteed to be called before dentry gets evicted. In other words, it is not suitable for any kind of keeping track of dentry state. None of the in-tree filesystems attempt to use it that way, fortunately. So the contortions done by fast_dput() (as well as dentry_kill()) are not warranted. fast_dput() certainly should treat having ->d_delete() instance as "can't assume we'll be keeping it", but that's not different from the way we treat e.g. DCACHE_DONTCACHE (which is rather similar to making ->d_delete() returns true when called). Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c12
1 files changed, 2 insertions, 10 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index c1025921f8d3..00c19041adf3 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -768,15 +768,7 @@ static inline bool fast_dput(struct dentry *dentry)
unsigned int d_flags;
/*
- * If we have a d_op->d_delete() operation, we sould not
- * let the dentry count go to zero, so use "put_or_lock".
- */
- if (unlikely(dentry->d_flags & DCACHE_OP_DELETE))
- return lockref_put_or_lock(&dentry->d_lockref);
-
- /*
- * .. otherwise, we can try to just decrement the
- * lockref optimistically.
+ * try to decrement the lockref optimistically.
*/
ret = lockref_put_return(&dentry->d_lockref);
@@ -830,7 +822,7 @@ static inline bool fast_dput(struct dentry *dentry)
*/
smp_rmb();
d_flags = READ_ONCE(dentry->d_flags);
- d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST |
+ d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST | DCACHE_OP_DELETE |
DCACHE_DISCONNECTED | DCACHE_DONTCACHE;
/* Nothing to do? Dropping the reference was all we needed? */