Skip to content

Commit

Permalink
vfs: use lockref_get_not_zero() for optimistic lockless dget_parent()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Waiman Long authored and Linus Torvalds committed Sep 2, 2013
1 parent b3abd80 commit df3d0bb
Showing 1 changed file with 15 additions and 0 deletions.
15 changes: 15 additions & 0 deletions fs/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,8 +611,23 @@ static inline void __dget(struct dentry *dentry)

struct dentry *dget_parent(struct dentry *dentry)
{
int gotref;
struct dentry *ret;

/*
* Do optimistic parent lookup without any
* locking.
*/
rcu_read_lock();
ret = ACCESS_ONCE(dentry->d_parent);
gotref = lockref_get_not_zero(&ret->d_lockref);
rcu_read_unlock();
if (likely(gotref)) {
if (likely(ret == ACCESS_ONCE(dentry->d_parent)))
return ret;
dput(ret);
}

repeat:
/*
* Don't need rcu_dereference because we re-check it was correct under
Expand Down

0 comments on commit df3d0bb

Please sign in to comment.