]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
d_walk(): shrink rcu_read_lock() scope
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 21 Apr 2026 19:52:13 +0000 (15:52 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 5 Jun 2026 04:34:55 +0000 (00:34 -0400)
we only need it to bridge over from ->d_lock scope of child to ->d_lock
scope of parent; dropping ->d_lock at rename_retry doesn't need to be
in rcu_read_lock() scope.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/dcache.c

index cf4bd6c37d04f81007c7f783b45ab43ab554b87e..94749442fa6899e61f1ec0cd4df4e72e115ec880 100644 (file)
@@ -1491,14 +1491,15 @@ resume:
        /*
         * All done at this level ... ascend and resume the search.
         */
-       rcu_read_lock();
 ascend:
        if (this_parent != parent) {
                dentry = this_parent;
                this_parent = dentry->d_parent;
 
+               rcu_read_lock();
                spin_unlock(&dentry->d_lock);
                spin_lock(&this_parent->d_lock);
+               rcu_read_unlock();
 
                /* might go back up the wrong parent if we have had a rename. */
                if (need_seqretry(&rename_lock, seq))
@@ -1506,7 +1507,6 @@ ascend:
                /* go into the first sibling still alive */
                hlist_for_each_entry_continue(dentry, d_sib) {
                        if (likely(!(dentry->d_flags & DCACHE_DENTRY_KILLED))) {
-                               rcu_read_unlock();
                                goto resume;
                        }
                }
@@ -1514,7 +1514,6 @@ ascend:
        }
        if (need_seqretry(&rename_lock, seq))
                goto rename_retry;
-       rcu_read_unlock();
 
 out_unlock:
        spin_unlock(&this_parent->d_lock);
@@ -1523,7 +1522,6 @@ out_unlock:
 
 rename_retry:
        spin_unlock(&this_parent->d_lock);
-       rcu_read_unlock();
        BUG_ON(seq & 1);
        if (!retry)
                return;