diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2018-02-24 04:11:34 +0100 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-03-29 21:07:42 +0200 |
commit | 8b987a46a1e0e93d4cb4babea06ea274e2e2b658 (patch) | |
tree | 3aef2007f7a60a820066cd3c1203d66bb3eee810 | |
parent | now lock_parent() can't run into killed dentry (diff) | |
download | linux-8b987a46a1e0e93d4cb4babea06ea274e2e2b658.tar.xz linux-8b987a46a1e0e93d4cb4babea06ea274e2e2b658.zip |
split the slow part of lock_parent() off
Turn the "trylock failed" part into uninlined __lock_parent().
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/dcache.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 916fd57b9d18..61819fb32e13 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -588,13 +588,9 @@ static void __dentry_kill(struct dentry *dentry) dentry_free(dentry); } -static inline struct dentry *lock_parent(struct dentry *dentry) +static struct dentry *__lock_parent(struct dentry *dentry) { - struct dentry *parent = dentry->d_parent; - if (IS_ROOT(dentry)) - return NULL; - if (likely(spin_trylock(&parent->d_lock))) - return parent; + struct dentry *parent; rcu_read_lock(); spin_unlock(&dentry->d_lock); again: @@ -620,6 +616,16 @@ again: return parent; } +static inline struct dentry *lock_parent(struct dentry *dentry) +{ + struct dentry *parent = dentry->d_parent; + if (IS_ROOT(dentry)) + return NULL; + if (likely(spin_trylock(&parent->d_lock))) + return parent; + return __lock_parent(dentry); +} + /* * Finish off a dentry we've decided to kill. * dentry->d_lock must be held, returns with it unlocked. |