diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:16:07 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:16:07 +0000 |
commit | 6b427072c86d5df3f3ee861826cfbd9f08306aff (patch) | |
tree | a0d639ae6079e84a6b0ff97c38f30fae8693a285 /fs/dcache.c | |
parent | Adding debian version 6.9.10-1. (diff) | |
download | linux-6b427072c86d5df3f3ee861826cfbd9f08306aff.tar.xz linux-6b427072c86d5df3f3ee861826cfbd9f08306aff.zip |
Merging upstream version 6.9.11.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 31 |
1 files changed, 14 insertions, 17 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 66515fbc9d..4c144519aa 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -3035,28 +3035,25 @@ EXPORT_SYMBOL(d_splice_alias); bool is_subdir(struct dentry *new_dentry, struct dentry *old_dentry) { - bool result; + bool subdir; unsigned seq; if (new_dentry == old_dentry) return true; - do { - /* for restarting inner loop in case of seq retry */ - seq = read_seqbegin(&rename_lock); - /* - * Need rcu_readlock to protect against the d_parent trashing - * due to d_move - */ - rcu_read_lock(); - if (d_ancestor(old_dentry, new_dentry)) - result = true; - else - result = false; - rcu_read_unlock(); - } while (read_seqretry(&rename_lock, seq)); - - return result; + /* Access d_parent under rcu as d_move() may change it. */ + rcu_read_lock(); + seq = read_seqbegin(&rename_lock); + subdir = d_ancestor(old_dentry, new_dentry); + /* Try lockless once... */ + if (read_seqretry(&rename_lock, seq)) { + /* ...else acquire lock for progress even on deep chains. */ + read_seqlock_excl(&rename_lock); + subdir = d_ancestor(old_dentry, new_dentry); + read_sequnlock_excl(&rename_lock); + } + rcu_read_unlock(); + return subdir; } EXPORT_SYMBOL(is_subdir); |