aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/dcache.h
diff options
context:
space:
mode:
authorWaiman Long <Waiman.Long@hp.com>2013-08-28 21:24:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-08-28 21:24:59 -0400
commit98474236f72e5a8b89c14cd7c74f0bb77a4b1a99 (patch)
treee07a431ce2f83162ea0643398a75d8ab5806b895 /include/linux/dcache.h
parent0f8f2aaaab0b0f9c13635cb02e7d19bdaa9aa1bb (diff)
vfs: make the dentry cache use the lockref infrastructure
This just replaces the dentry count/lock combination with the lockref structure that contains both a count and a spinlock, and does the mechanical conversion to use the lockref infrastructure. There are no semantic changes here, it's purely syntactic. The reference lockref implementation uses the spinlock exactly the same way that the old dcache code did, and the bulk of this patch is just expanding the internal "d_count" use in the dcache code to use "d_lockref.count" instead. This is purely preparation for the real change to make the reference count updates be lockless during the 3.12 merge window. [ As with the previous commit, this is a rewritten version of a concept originally from Waiman, so credit goes to him, blame for any errors goes to me. Waiman's patch had some semantic differences for taking advantage of the lockless update in dget_parent(), while this patch is intentionally a pure search-and-replace change with no semantic changes. - Linus ] Signed-off-by: Waiman Long <Waiman.Long@hp.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/dcache.h')
-rw-r--r--include/linux/dcache.h19
1 files changed, 9 insertions, 10 deletions
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 4a12532da8c4..efdc94434c30 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -9,6 +9,7 @@
9#include <linux/seqlock.h> 9#include <linux/seqlock.h>
10#include <linux/cache.h> 10#include <linux/cache.h>
11#include <linux/rcupdate.h> 11#include <linux/rcupdate.h>
12#include <linux/lockref.h>
12 13
13struct nameidata; 14struct nameidata;
14struct path; 15struct path;
@@ -100,6 +101,8 @@ extern unsigned int full_name_hash(const unsigned char *, unsigned int);
100# endif 101# endif
101#endif 102#endif
102 103
104#define d_lock d_lockref.lock
105
103struct dentry { 106struct dentry {
104 /* RCU lookup touched fields */ 107 /* RCU lookup touched fields */
105 unsigned int d_flags; /* protected by d_lock */ 108 unsigned int d_flags; /* protected by d_lock */
@@ -112,8 +115,7 @@ struct dentry {
112 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */ 115 unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
113 116
114 /* Ref lookup also touches following */ 117 /* Ref lookup also touches following */
115 unsigned int d_count; /* protected by d_lock */ 118 struct lockref d_lockref; /* per-dentry lock and refcount */
116 spinlock_t d_lock; /* per dentry lock */
117 const struct dentry_operations *d_op; 119 const struct dentry_operations *d_op;
118 struct super_block *d_sb; /* The root of the dentry tree */ 120 struct super_block *d_sb; /* The root of the dentry tree */
119 unsigned long d_time; /* used by d_revalidate */ 121 unsigned long d_time; /* used by d_revalidate */
@@ -318,7 +320,7 @@ static inline int __d_rcu_to_refcount(struct dentry *dentry, unsigned seq)
318 assert_spin_locked(&dentry->d_lock); 320 assert_spin_locked(&dentry->d_lock);
319 if (!read_seqcount_retry(&dentry->d_seq, seq)) { 321 if (!read_seqcount_retry(&dentry->d_seq, seq)) {
320 ret = 1; 322 ret = 1;
321 dentry->d_count++; 323 dentry->d_lockref.count++;
322 } 324 }
323 325
324 return ret; 326 return ret;
@@ -326,7 +328,7 @@ static inline int __d_rcu_to_refcount(struct dentry *dentry, unsigned seq)
326 328
327static inline unsigned d_count(const struct dentry *dentry) 329static inline unsigned d_count(const struct dentry *dentry)
328{ 330{
329 return dentry->d_count; 331 return dentry->d_lockref.count;
330} 332}
331 333
332/* validate "insecure" dentry pointer */ 334/* validate "insecure" dentry pointer */
@@ -357,17 +359,14 @@ extern char *dentry_path(struct dentry *, char *, int);
357static inline struct dentry *dget_dlock(struct dentry *dentry) 359static inline struct dentry *dget_dlock(struct dentry *dentry)
358{ 360{
359 if (dentry) 361 if (dentry)
360 dentry->d_count++; 362 dentry->d_lockref.count++;
361 return dentry; 363 return dentry;
362} 364}
363 365
364static inline struct dentry *dget(struct dentry *dentry) 366static inline struct dentry *dget(struct dentry *dentry)
365{ 367{
366 if (dentry) { 368 if (dentry)
367 spin_lock(&dentry->d_lock); 369 lockref_get(&dentry->d_lockref);
368 dget_dlock(dentry);
369 spin_unlock(&dentry->d_lock);
370 }
371 return dentry; 370 return dentry;
372} 371}
373 372