diff options
author | Waiman Long <Waiman.Long@hp.com> | 2013-08-28 21:24:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-28 21:24:59 -0400 |
commit | 98474236f72e5a8b89c14cd7c74f0bb77a4b1a99 (patch) | |
tree | e07a431ce2f83162ea0643398a75d8ab5806b895 /include/linux/dcache.h | |
parent | 0f8f2aaaab0b0f9c13635cb02e7d19bdaa9aa1bb (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.h | 19 |
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 | ||
13 | struct nameidata; | 14 | struct nameidata; |
14 | struct path; | 15 | struct 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 | |||
103 | struct dentry { | 106 | struct 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 | ||
327 | static inline unsigned d_count(const struct dentry *dentry) | 329 | static 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); | |||
357 | static inline struct dentry *dget_dlock(struct dentry *dentry) | 359 | static 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 | ||
364 | static inline struct dentry *dget(struct dentry *dentry) | 366 | static 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 | ||