diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2018-02-23 22:07:35 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-03-29 15:07:42 -0400 |
commit | 65d8eb5a8f5480756105173de147ef5d60163e2f (patch) | |
tree | b06ff6ae3eb019432b827bf8620a38630a0f011f | |
parent | 3b3f09f48ba78c0634e929849860a6447d057eed (diff) |
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>
-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) | |||
593 | struct dentry *parent = dentry->d_parent; | 593 | struct dentry *parent = dentry->d_parent; |
594 | if (IS_ROOT(dentry)) | 594 | if (IS_ROOT(dentry)) |
595 | return NULL; | 595 | return NULL; |
596 | if (unlikely(dentry->d_lockref.count < 0)) | ||
597 | return NULL; | ||
598 | if (likely(spin_trylock(&parent->d_lock))) | 596 | if (likely(spin_trylock(&parent->d_lock))) |
599 | return parent; | 597 | return parent; |
600 | rcu_read_lock(); | 598 | rcu_read_lock(); |
@@ -614,16 +612,11 @@ again: | |||
614 | spin_unlock(&parent->d_lock); | 612 | spin_unlock(&parent->d_lock); |
615 | goto again; | 613 | goto again; |
616 | } | 614 | } |
617 | if (parent != dentry) { | 615 | rcu_read_unlock(); |
616 | if (parent != dentry) | ||
618 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); | 617 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); |
619 | if (unlikely(dentry->d_lockref.count < 0)) { | 618 | else |
620 | spin_unlock(&parent->d_lock); | ||
621 | parent = NULL; | ||
622 | } | ||
623 | } else { | ||
624 | parent = NULL; | 619 | parent = NULL; |
625 | } | ||
626 | rcu_read_unlock(); | ||
627 | return parent; | 620 | return parent; |
628 | } | 621 | } |
629 | 622 | ||