aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2018-02-23 22:07:35 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2018-03-29 15:07:42 -0400
commit65d8eb5a8f5480756105173de147ef5d60163e2f (patch)
treeb06ff6ae3eb019432b827bf8620a38630a0f011f
parent3b3f09f48ba78c0634e929849860a6447d057eed (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.c13
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