diff options
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 | ||