aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/dcache.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index b949af850cd6..2d244227999d 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -611,8 +611,23 @@ static inline void __dget(struct dentry *dentry)
611 611
612struct dentry *dget_parent(struct dentry *dentry) 612struct dentry *dget_parent(struct dentry *dentry)
613{ 613{
614 int gotref;
614 struct dentry *ret; 615 struct dentry *ret;
615 616
617 /*
618 * Do optimistic parent lookup without any
619 * locking.
620 */
621 rcu_read_lock();
622 ret = ACCESS_ONCE(dentry->d_parent);
623 gotref = lockref_get_not_zero(&ret->d_lockref);
624 rcu_read_unlock();
625 if (likely(gotref)) {
626 if (likely(ret == ACCESS_ONCE(dentry->d_parent)))
627 return ret;
628 dput(ret);
629 }
630
616repeat: 631repeat:
617 /* 632 /*
618 * Don't need rcu_dereference because we re-check it was correct under 633 * Don't need rcu_dereference because we re-check it was correct under