summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2026-04-21 15:52:13 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2026-06-05 00:34:55 -0400
commit3ef89feb387f2da13df290ce3e38fe8284160a86 (patch)
tree6f93c242e76943663839738d0843f48f843ea442
parent4af0cdb5765ad15f4175bc94ca20b8deb2c7ebde (diff)
d_walk(): shrink rcu_read_lock() scope
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>
-rw-r--r--fs/dcache.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index cf4bd6c37d04..94749442fa68 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -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;