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>
This commit is contained in:
Al Viro 2026-04-21 15:52:13 -04:00
parent 4af0cdb576
commit 3ef89feb38

View File

@ -1491,14 +1491,15 @@ static void d_walk(struct dentry *parent, void *data,
/*
* 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 @@ static void d_walk(struct dentry *parent, void *data,
/* 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 @@ static void d_walk(struct dentry *parent, void *data,
}
if (need_seqretry(&rename_lock, seq))
goto rename_retry;
rcu_read_unlock();
out_unlock:
spin_unlock(&this_parent->d_lock);
@ -1523,7 +1522,6 @@ static void d_walk(struct dentry *parent, void *data,
rename_retry:
spin_unlock(&this_parent->d_lock);
rcu_read_unlock();
BUG_ON(seq & 1);
if (!retry)
return;