summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2026-04-11 03:14:19 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2026-06-05 00:34:55 -0400
commitd60ac70f3f261529a52ac70b514a02651ebd5dc3 (patch)
tree21b24de86cb139cc8b8c6801ba3b02fb36f0ca08
parent500590a897d9edadfffaed09f25f67ed7cd1813b (diff)
downloadlinux-d60ac70f3f261529a52ac70b514a02651ebd5dc3.tar.gz
linux-d60ac70f3f261529a52ac70b514a02651ebd5dc3.zip
fold lock_for_kill() and __dentry_kill() into common helper
There are two callers of lock_for_kill() and both are followed by the same sequence of actions: * in case of failure, drop ->d_lock, do rcu_read_unlock() and go away * in case of success, do rcu_read_unlock() followed by passing dentry to __dentry_kill(); if the latter returns NULL, go away. All calls of __dentry_kill() are paired with lock_for_kill() now; let's turn that sequence into a new helper (dentry_kill()) and switch to using it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/dcache.c28
1 files changed, 13 insertions, 15 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 3325ca535bf6..1dfe37e57447 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -779,6 +779,17 @@ static bool lock_for_kill(struct dentry *dentry)
return false;
}
+static struct dentry *dentry_kill(struct dentry *dentry)
+{
+ if (unlikely(!lock_for_kill(dentry))) {
+ spin_unlock(&dentry->d_lock);
+ rcu_read_unlock();
+ return NULL;
+ }
+ rcu_read_unlock();
+ return __dentry_kill(dentry);
+}
+
/*
* Decide if dentry is worth retaining. Usually this is called with dentry
* locked; if not locked, we are more limited and might not be able to tell
@@ -922,19 +933,13 @@ static void finish_dput(struct dentry *dentry)
__releases(dentry->d_lock)
__releases(RCU)
{
- while (lock_for_kill(dentry)) {
- rcu_read_unlock();
- dentry = __dentry_kill(dentry);
- if (!dentry)
- return;
+ while ((dentry = dentry_kill(dentry)) != NULL) {
if (retain_dentry(dentry, true)) {
spin_unlock(&dentry->d_lock);
return;
}
rcu_read_lock();
}
- rcu_read_unlock();
- spin_unlock(&dentry->d_lock);
}
/*
@@ -1211,15 +1216,8 @@ EXPORT_SYMBOL(d_prune_aliases);
static inline void shrink_kill(struct dentry *victim)
{
- while (lock_for_kill(victim)) {
- rcu_read_unlock();
- victim = __dentry_kill(victim);
- if (!victim)
- return;
+ while ((victim = dentry_kill(victim)) != NULL)
rcu_read_lock();
- }
- spin_unlock(&victim->d_lock);
- rcu_read_unlock();
}
void shrink_dentry_list(struct list_head *list)