aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorWaiman Long <Waiman.Long@hp.com>2013-09-02 14:29:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-02 14:29:22 -0400
commitdf3d0bbcdb2cafa23a70223d806655bd37e64a9b (patch)
treee25e1f06ad304ab4c87293f37961b8e97d7fd242 /fs/dcache.c
parentb3abd80250c13414bc258b53e57242feb159af91 (diff)
vfs: use lockref_get_not_zero() for optimistic lockless dget_parent()
A valid parent pointer is always going to have a non-zero reference count, but if we look up the parent optimistically without locking, we have to protect against the (very unlikely) race against renaming changing the parent from under us. We do that by using lockref_get_not_zero(), and then re-checking the parent pointer after getting a valid reference. [ This is a re-implementation of a chunk from the original patch by Waiman Long: "dcache: Enable lockless update of dentry's refcount". I've completely rewritten the patch-series and split it up, but I'm attributing this part to Waiman as it's close enough to his earlier patch - Linus ] Signed-off-by: Waiman Long <Waiman.Long@hp.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/dcache.c')
-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