]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
fold lock_for_kill() and __dentry_kill() into common helper
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 11 Apr 2026 07:14:19 +0000 (03:14 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 5 Jun 2026 04:34:55 +0000 (00:34 -0400)
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>
fs/dcache.c

index 3325ca535bf6bf91e598567488cc8fdee3ccf53e..1dfe37e574473fe4c55e99f91484de476f67e74f 100644 (file)
@@ -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)