diff options
-rw-r--r-- | fs/dcache.c | 15 |
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 | ||
612 | struct dentry *dget_parent(struct dentry *dentry) | 612 | struct 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 | |||
616 | repeat: | 631 | repeat: |
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 |