summaryrefslogtreecommitdiff
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2023-10-31 01:41:22 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2023-11-25 02:34:12 -0500
commit5e7a5c8d17d94216aed205cb0f20cd32adfd4487 (patch)
treee837414f65a8f39a9b216e369ee9cfbe78da4893 /fs/dcache.c
parent339e9e13530ba750fe0868c5e51bc23be07fd1f1 (diff)
fold dentry_kill() into dput()
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.c37
1 files changed, 12 insertions, 25 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index a7f99d46c41b..5284b02747cd 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -757,28 +757,6 @@ void d_mark_dontcache(struct inode *inode)
EXPORT_SYMBOL(d_mark_dontcache);
/*
- * Finish off a dentry we've decided to kill.
- * dentry->d_lock must be held, returns with it unlocked.
- * Returns dentry requiring refcount drop, or NULL if we're done.
- */
-static struct dentry *dentry_kill(struct dentry *dentry)
- __releases(dentry->d_lock)
-{
-
- dentry->d_lockref.count--;
- rcu_read_lock();
- if (likely(lock_for_kill(dentry))) {
- struct dentry *parent = dentry->d_parent;
- rcu_read_unlock();
- __dentry_kill(dentry);
- return parent != dentry ? parent : NULL;
- }
- rcu_read_unlock();
- spin_unlock(&dentry->d_lock);
- return NULL;
-}
-
-/*
* Try to do a lockless dput(), and return whether that was successful.
*
* If unsuccessful, we return false, having already taken the dentry lock.
@@ -915,9 +893,18 @@ void dput(struct dentry *dentry)
}
/* Slow case: now with the dentry lock held */
- rcu_read_unlock();
- dentry->d_lockref.count = 1;
- dentry = dentry_kill(dentry);
+ if (likely(lock_for_kill(dentry))) {
+ struct dentry *parent = dentry->d_parent;
+ rcu_read_unlock();
+ __dentry_kill(dentry);
+ if (dentry == parent)
+ return;
+ dentry = parent;
+ } else {
+ rcu_read_unlock();
+ spin_unlock(&dentry->d_lock);
+ return;
+ }
}
}
EXPORT_SYMBOL(dput);