diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2018-02-24 04:07:35 +0100 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-03-29 21:07:42 +0200 |
commit | 65d8eb5a8f5480756105173de147ef5d60163e2f (patch) | |
tree | b06ff6ae3eb019432b827bf8620a38630a0f011f /fs/dcache.c | |
parent | get rid of trylock loop in locking dentries on shrink list (diff) | |
download | linux-65d8eb5a8f5480756105173de147ef5d60163e2f.tar.xz linux-65d8eb5a8f5480756105173de147ef5d60163e2f.zip |
now lock_parent() can't run into killed dentry
all remaining callers hold either a reference or ->i_lock
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 13 |
1 files changed, 3 insertions, 10 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index af8501489af5..916fd57b9d18 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -593,8 +593,6 @@ static inline struct dentry *lock_parent(struct dentry *dentry) struct dentry *parent = dentry->d_parent; if (IS_ROOT(dentry)) return NULL; - if (unlikely(dentry->d_lockref.count < 0)) - return NULL; if (likely(spin_trylock(&parent->d_lock))) return parent; rcu_read_lock(); @@ -614,16 +612,11 @@ again: spin_unlock(&parent->d_lock); goto again; } - if (parent != dentry) { + rcu_read_unlock(); + if (parent != dentry) spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); - if (unlikely(dentry->d_lockref.count < 0)) { - spin_unlock(&parent->d_lock); - parent = NULL; - } - } else { + else parent = NULL; - } - rcu_read_unlock(); return parent; } |