aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Piggin <npiggin@kernel.dk>2011-01-07 01:49:33 -0500
committerNick Piggin <npiggin@kernel.dk>2011-01-07 01:50:21 -0500
commitda5029563a0a026c64821b09e8e7b4fd81d3fe1b (patch)
tree5d5618e0cb382390073377b1be7d0aa76879ac54
parentb7ab39f631f505edc2bbdb86620d5493f995c9da (diff)
fs: dcache scale d_unhashed
Protect d_unhashed(dentry) condition with d_lock. This means keeping DCACHE_UNHASHED bit in synch with hash manipulations. Signed-off-by: Nick Piggin <npiggin@kernel.dk>
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c3
-rw-r--r--drivers/usb/core/inode.c3
-rw-r--r--fs/autofs4/autofs_i.h13
-rw-r--r--fs/autofs4/expire.c21
-rw-r--r--fs/ceph/dir.c5
-rw-r--r--fs/configfs/configfs_internal.h2
-rw-r--r--fs/dcache.c74
-rw-r--r--fs/libfs.c29
-rw-r--r--fs/ocfs2/dcache.c5
-rw-r--r--security/tomoyo/realpath.c1
10 files changed, 102 insertions, 54 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 29a406a77547..5aef1a7f5e4b 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -166,6 +166,9 @@ static void spufs_prune_dir(struct dentry *dir)
166 __d_drop(dentry); 166 __d_drop(dentry);
167 spin_unlock(&dentry->d_lock); 167 spin_unlock(&dentry->d_lock);
168 simple_unlink(dir->d_inode, dentry); 168 simple_unlink(dir->d_inode, dentry);
169 /* XXX: what is dcache_lock protecting here? Other
170 * filesystems (IB, configfs) release dcache_lock
171 * before unlink */
169 spin_unlock(&dcache_lock); 172 spin_unlock(&dcache_lock);
170 dput(dentry); 173 dput(dentry);
171 } else { 174 } else {
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index b690aa35df9a..e3ab4437ea96 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -347,10 +347,13 @@ static int usbfs_empty (struct dentry *dentry)
347 347
348 list_for_each(list, &dentry->d_subdirs) { 348 list_for_each(list, &dentry->d_subdirs) {
349 struct dentry *de = list_entry(list, struct dentry, d_u.d_child); 349 struct dentry *de = list_entry(list, struct dentry, d_u.d_child);
350 spin_lock(&de->d_lock);
350 if (usbfs_positive(de)) { 351 if (usbfs_positive(de)) {
352 spin_unlock(&de->d_lock);
351 spin_unlock(&dcache_lock); 353 spin_unlock(&dcache_lock);
352 return 0; 354 return 0;
353 } 355 }
356 spin_unlock(&de->d_lock);
354 } 357 }
355 358
356 spin_unlock(&dcache_lock); 359 spin_unlock(&dcache_lock);
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index 3d283abf67d7..3912dcf047e5 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -254,19 +254,6 @@ static inline int simple_positive(struct dentry *dentry)
254 return dentry->d_inode && !d_unhashed(dentry); 254 return dentry->d_inode && !d_unhashed(dentry);
255} 255}
256 256
257static inline int __simple_empty(struct dentry *dentry)
258{
259 struct dentry *child;
260 int ret = 0;
261
262 list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child)
263 if (simple_positive(child))
264 goto out;
265 ret = 1;
266out:
267 return ret;
268}
269
270static inline void autofs4_add_expiring(struct dentry *dentry) 257static inline void autofs4_add_expiring(struct dentry *dentry)
271{ 258{
272 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); 259 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 413b5642e6cf..ee6402050f13 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -160,14 +160,18 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
160 160
161 spin_lock(&dcache_lock); 161 spin_lock(&dcache_lock);
162 for (p = top; p; p = next_dentry(p, top)) { 162 for (p = top; p; p = next_dentry(p, top)) {
163 spin_lock(&p->d_lock);
163 /* Negative dentry - give up */ 164 /* Negative dentry - give up */
164 if (!simple_positive(p)) 165 if (!simple_positive(p)) {
166 spin_unlock(&p->d_lock);
165 continue; 167 continue;
168 }
166 169
167 DPRINTK("dentry %p %.*s", 170 DPRINTK("dentry %p %.*s",
168 p, (int) p->d_name.len, p->d_name.name); 171 p, (int) p->d_name.len, p->d_name.name);
169 172
170 p = dget(p); 173 p = dget_dlock(p);
174 spin_unlock(&p->d_lock);
171 spin_unlock(&dcache_lock); 175 spin_unlock(&dcache_lock);
172 176
173 /* 177 /*
@@ -228,14 +232,18 @@ static struct dentry *autofs4_check_leaves(struct vfsmount *mnt,
228 232
229 spin_lock(&dcache_lock); 233 spin_lock(&dcache_lock);
230 for (p = parent; p; p = next_dentry(p, parent)) { 234 for (p = parent; p; p = next_dentry(p, parent)) {
235 spin_lock(&p->d_lock);
231 /* Negative dentry - give up */ 236 /* Negative dentry - give up */
232 if (!simple_positive(p)) 237 if (!simple_positive(p)) {
238 spin_unlock(&p->d_lock);
233 continue; 239 continue;
240 }
234 241
235 DPRINTK("dentry %p %.*s", 242 DPRINTK("dentry %p %.*s",
236 p, (int) p->d_name.len, p->d_name.name); 243 p, (int) p->d_name.len, p->d_name.name);
237 244
238 p = dget(p); 245 p = dget_dlock(p);
246 spin_unlock(&p->d_lock);
239 spin_unlock(&dcache_lock); 247 spin_unlock(&dcache_lock);
240 248
241 if (d_mountpoint(p)) { 249 if (d_mountpoint(p)) {
@@ -324,12 +332,15 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
324 struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child); 332 struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
325 333
326 /* Negative dentry - give up */ 334 /* Negative dentry - give up */
335 spin_lock(&dentry->d_lock);
327 if (!simple_positive(dentry)) { 336 if (!simple_positive(dentry)) {
328 next = next->next; 337 next = next->next;
338 spin_unlock(&dentry->d_lock);
329 continue; 339 continue;
330 } 340 }
331 341
332 dentry = dget(dentry); 342 dentry = dget_dlock(dentry);
343 spin_unlock(&dentry->d_lock);
333 spin_unlock(&dcache_lock); 344 spin_unlock(&dcache_lock);
334 345
335 spin_lock(&sbi->fs_lock); 346 spin_lock(&sbi->fs_lock);
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 3ecf915a4550..571f270dca0f 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -136,6 +136,7 @@ more:
136 fi->at_end = 1; 136 fi->at_end = 1;
137 goto out_unlock; 137 goto out_unlock;
138 } 138 }
139 spin_lock(&dentry->d_lock);
139 if (!d_unhashed(dentry) && dentry->d_inode && 140 if (!d_unhashed(dentry) && dentry->d_inode &&
140 ceph_snap(dentry->d_inode) != CEPH_SNAPDIR && 141 ceph_snap(dentry->d_inode) != CEPH_SNAPDIR &&
141 ceph_ino(dentry->d_inode) != CEPH_INO_CEPH && 142 ceph_ino(dentry->d_inode) != CEPH_INO_CEPH &&
@@ -145,13 +146,13 @@ more:
145 dentry->d_name.len, dentry->d_name.name, di->offset, 146 dentry->d_name.len, dentry->d_name.name, di->offset,
146 filp->f_pos, d_unhashed(dentry) ? " unhashed" : "", 147 filp->f_pos, d_unhashed(dentry) ? " unhashed" : "",
147 !dentry->d_inode ? " null" : ""); 148 !dentry->d_inode ? " null" : "");
149 spin_unlock(&dentry->d_lock);
148 p = p->prev; 150 p = p->prev;
149 dentry = list_entry(p, struct dentry, d_u.d_child); 151 dentry = list_entry(p, struct dentry, d_u.d_child);
150 di = ceph_dentry(dentry); 152 di = ceph_dentry(dentry);
151 } 153 }
152 154
153 spin_lock(&dentry->d_lock); 155 dget_dlock(dentry);
154 dentry->d_count++;
155 spin_unlock(&dentry->d_lock); 156 spin_unlock(&dentry->d_lock);
156 spin_unlock(&dcache_lock); 157 spin_unlock(&dcache_lock);
157 158
diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h
index da6061a6df40..e58b4c30e216 100644
--- a/fs/configfs/configfs_internal.h
+++ b/fs/configfs/configfs_internal.h
@@ -121,6 +121,7 @@ static inline struct config_item *configfs_get_config_item(struct dentry *dentry
121 struct config_item * item = NULL; 121 struct config_item * item = NULL;
122 122
123 spin_lock(&dcache_lock); 123 spin_lock(&dcache_lock);
124 spin_lock(&dentry->d_lock);
124 if (!d_unhashed(dentry)) { 125 if (!d_unhashed(dentry)) {
125 struct configfs_dirent * sd = dentry->d_fsdata; 126 struct configfs_dirent * sd = dentry->d_fsdata;
126 if (sd->s_type & CONFIGFS_ITEM_LINK) { 127 if (sd->s_type & CONFIGFS_ITEM_LINK) {
@@ -129,6 +130,7 @@ static inline struct config_item *configfs_get_config_item(struct dentry *dentry
129 } else 130 } else
130 item = config_item_get(sd->s_element); 131 item = config_item_get(sd->s_element);
131 } 132 }
133 spin_unlock(&dentry->d_lock);
132 spin_unlock(&dcache_lock); 134 spin_unlock(&dcache_lock);
133 135
134 return item; 136 return item;
diff --git a/fs/dcache.c b/fs/dcache.c
index 81e91502b294..ee127f9ab274 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -46,6 +46,7 @@
46 * - d_name 46 * - d_name
47 * - d_lru 47 * - d_lru
48 * - d_count 48 * - d_count
49 * - d_unhashed()
49 * 50 *
50 * Ordering: 51 * Ordering:
51 * dcache_lock 52 * dcache_lock
@@ -53,6 +54,13 @@
53 * dcache_lru_lock 54 * dcache_lru_lock
54 * dcache_hash_lock 55 * dcache_hash_lock
55 * 56 *
57 * If there is an ancestor relationship:
58 * dentry->d_parent->...->d_parent->d_lock
59 * ...
60 * dentry->d_parent->d_lock
61 * dentry->d_lock
62 *
63 * If no ancestor relationship:
56 * if (dentry1 < dentry2) 64 * if (dentry1 < dentry2)
57 * dentry1->d_lock 65 * dentry1->d_lock
58 * dentry2->d_lock 66 * dentry2->d_lock
@@ -379,7 +387,9 @@ int d_invalidate(struct dentry * dentry)
379 * If it's already been dropped, return OK. 387 * If it's already been dropped, return OK.
380 */ 388 */
381 spin_lock(&dcache_lock); 389 spin_lock(&dcache_lock);
390 spin_lock(&dentry->d_lock);
382 if (d_unhashed(dentry)) { 391 if (d_unhashed(dentry)) {
392 spin_unlock(&dentry->d_lock);
383 spin_unlock(&dcache_lock); 393 spin_unlock(&dcache_lock);
384 return 0; 394 return 0;
385 } 395 }
@@ -388,9 +398,11 @@ int d_invalidate(struct dentry * dentry)
388 * to get rid of unused child entries. 398 * to get rid of unused child entries.
389 */ 399 */
390 if (!list_empty(&dentry->d_subdirs)) { 400 if (!list_empty(&dentry->d_subdirs)) {
401 spin_unlock(&dentry->d_lock);
391 spin_unlock(&dcache_lock); 402 spin_unlock(&dcache_lock);
392 shrink_dcache_parent(dentry); 403 shrink_dcache_parent(dentry);
393 spin_lock(&dcache_lock); 404 spin_lock(&dcache_lock);
405 spin_lock(&dentry->d_lock);
394 } 406 }
395 407
396 /* 408 /*
@@ -403,7 +415,6 @@ int d_invalidate(struct dentry * dentry)
403 * we might still populate it if it was a 415 * we might still populate it if it was a
404 * working directory or similar). 416 * working directory or similar).
405 */ 417 */
406 spin_lock(&dentry->d_lock);
407 if (dentry->d_count > 1) { 418 if (dentry->d_count > 1) {
408 if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) { 419 if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) {
409 spin_unlock(&dentry->d_lock); 420 spin_unlock(&dentry->d_lock);
@@ -490,35 +501,44 @@ EXPORT_SYMBOL(dget_parent);
490 * any other hashed alias over that one unless @want_discon is set, 501 * any other hashed alias over that one unless @want_discon is set,
491 * in which case only return an IS_ROOT, DCACHE_DISCONNECTED alias. 502 * in which case only return an IS_ROOT, DCACHE_DISCONNECTED alias.
492 */ 503 */
493 504static struct dentry *__d_find_alias(struct inode *inode, int want_discon)
494static struct dentry * __d_find_alias(struct inode *inode, int want_discon)
495{ 505{
496 struct list_head *head, *next, *tmp; 506 struct dentry *alias, *discon_alias;
497 struct dentry *alias, *discon_alias=NULL;
498 507
499 head = &inode->i_dentry; 508again:
500 next = inode->i_dentry.next; 509 discon_alias = NULL;
501 while (next != head) { 510 list_for_each_entry(alias, &inode->i_dentry, d_alias) {
502 tmp = next; 511 spin_lock(&alias->d_lock);
503 next = tmp->next;
504 prefetch(next);
505 alias = list_entry(tmp, struct dentry, d_alias);
506 if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) { 512 if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
507 if (IS_ROOT(alias) && 513 if (IS_ROOT(alias) &&
508 (alias->d_flags & DCACHE_DISCONNECTED)) 514 (alias->d_flags & DCACHE_DISCONNECTED)) {
509 discon_alias = alias; 515 discon_alias = alias;
510 else if (!want_discon) { 516 } else if (!want_discon) {
511 __dget_locked(alias); 517 __dget_locked_dlock(alias);
518 spin_unlock(&alias->d_lock);
519 return alias;
520 }
521 }
522 spin_unlock(&alias->d_lock);
523 }
524 if (discon_alias) {
525 alias = discon_alias;
526 spin_lock(&alias->d_lock);
527 if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
528 if (IS_ROOT(alias) &&
529 (alias->d_flags & DCACHE_DISCONNECTED)) {
530 __dget_locked_dlock(alias);
531 spin_unlock(&alias->d_lock);
512 return alias; 532 return alias;
513 } 533 }
514 } 534 }
535 spin_unlock(&alias->d_lock);
536 goto again;
515 } 537 }
516 if (discon_alias) 538 return NULL;
517 __dget_locked(discon_alias);
518 return discon_alias;
519} 539}
520 540
521struct dentry * d_find_alias(struct inode *inode) 541struct dentry *d_find_alias(struct inode *inode)
522{ 542{
523 struct dentry *de = NULL; 543 struct dentry *de = NULL;
524 544
@@ -801,8 +821,8 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
801 spin_lock(&dcache_lock); 821 spin_lock(&dcache_lock);
802 spin_lock(&dentry->d_lock); 822 spin_lock(&dentry->d_lock);
803 dentry_lru_del(dentry); 823 dentry_lru_del(dentry);
804 spin_unlock(&dentry->d_lock);
805 __d_drop(dentry); 824 __d_drop(dentry);
825 spin_unlock(&dentry->d_lock);
806 spin_unlock(&dcache_lock); 826 spin_unlock(&dcache_lock);
807 827
808 for (;;) { 828 for (;;) {
@@ -817,8 +837,8 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
817 d_u.d_child) { 837 d_u.d_child) {
818 spin_lock(&loop->d_lock); 838 spin_lock(&loop->d_lock);
819 dentry_lru_del(loop); 839 dentry_lru_del(loop);
820 spin_unlock(&loop->d_lock);
821 __d_drop(loop); 840 __d_drop(loop);
841 spin_unlock(&loop->d_lock);
822 cond_resched_lock(&dcache_lock); 842 cond_resched_lock(&dcache_lock);
823 } 843 }
824 spin_unlock(&dcache_lock); 844 spin_unlock(&dcache_lock);
@@ -1863,7 +1883,10 @@ static void d_move_locked(struct dentry * dentry, struct dentry * target)
1863 /* 1883 /*
1864 * XXXX: do we really need to take target->d_lock? 1884 * XXXX: do we really need to take target->d_lock?
1865 */ 1885 */
1866 if (target < dentry) { 1886 if (d_ancestor(dentry, target)) {
1887 spin_lock(&dentry->d_lock);
1888 spin_lock_nested(&target->d_lock, DENTRY_D_LOCK_NESTED);
1889 } else if (d_ancestor(target, dentry) || target < dentry) {
1867 spin_lock(&target->d_lock); 1890 spin_lock(&target->d_lock);
1868 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); 1891 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
1869 } else { 1892 } else {
@@ -2542,13 +2565,16 @@ resume:
2542 struct list_head *tmp = next; 2565 struct list_head *tmp = next;
2543 struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child); 2566 struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
2544 next = tmp->next; 2567 next = tmp->next;
2545 if (d_unhashed(dentry)||!dentry->d_inode) 2568 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
2569 if (d_unhashed(dentry) || !dentry->d_inode) {
2570 spin_unlock(&dentry->d_lock);
2546 continue; 2571 continue;
2572 }
2547 if (!list_empty(&dentry->d_subdirs)) { 2573 if (!list_empty(&dentry->d_subdirs)) {
2574 spin_unlock(&dentry->d_lock);
2548 this_parent = dentry; 2575 this_parent = dentry;
2549 goto repeat; 2576 goto repeat;
2550 } 2577 }
2551 spin_lock(&dentry->d_lock);
2552 dentry->d_count--; 2578 dentry->d_count--;
2553 spin_unlock(&dentry->d_lock); 2579 spin_unlock(&dentry->d_lock);
2554 } 2580 }
diff --git a/fs/libfs.c b/fs/libfs.c
index b9d25d83e228..433e7139c23a 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -16,6 +16,11 @@
16 16
17#include <asm/uaccess.h> 17#include <asm/uaccess.h>
18 18
19static inline int simple_positive(struct dentry *dentry)
20{
21 return dentry->d_inode && !d_unhashed(dentry);
22}
23
19int simple_getattr(struct vfsmount *mnt, struct dentry *dentry, 24int simple_getattr(struct vfsmount *mnt, struct dentry *dentry,
20 struct kstat *stat) 25 struct kstat *stat)
21{ 26{
@@ -100,8 +105,10 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
100 while (n && p != &file->f_path.dentry->d_subdirs) { 105 while (n && p != &file->f_path.dentry->d_subdirs) {
101 struct dentry *next; 106 struct dentry *next;
102 next = list_entry(p, struct dentry, d_u.d_child); 107 next = list_entry(p, struct dentry, d_u.d_child);
103 if (!d_unhashed(next) && next->d_inode) 108 spin_lock(&next->d_lock);
109 if (simple_positive(next))
104 n--; 110 n--;
111 spin_unlock(&next->d_lock);
105 p = p->next; 112 p = p->next;
106 } 113 }
107 list_add_tail(&cursor->d_u.d_child, p); 114 list_add_tail(&cursor->d_u.d_child, p);
@@ -155,9 +162,13 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
155 for (p=q->next; p != &dentry->d_subdirs; p=p->next) { 162 for (p=q->next; p != &dentry->d_subdirs; p=p->next) {
156 struct dentry *next; 163 struct dentry *next;
157 next = list_entry(p, struct dentry, d_u.d_child); 164 next = list_entry(p, struct dentry, d_u.d_child);
158 if (d_unhashed(next) || !next->d_inode) 165 spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
166 if (!simple_positive(next)) {
167 spin_unlock(&next->d_lock);
159 continue; 168 continue;
169 }
160 170
171 spin_unlock(&next->d_lock);
161 spin_unlock(&dcache_lock); 172 spin_unlock(&dcache_lock);
162 if (filldir(dirent, next->d_name.name, 173 if (filldir(dirent, next->d_name.name,
163 next->d_name.len, filp->f_pos, 174 next->d_name.len, filp->f_pos,
@@ -259,20 +270,20 @@ int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *den
259 return 0; 270 return 0;
260} 271}
261 272
262static inline int simple_positive(struct dentry *dentry)
263{
264 return dentry->d_inode && !d_unhashed(dentry);
265}
266
267int simple_empty(struct dentry *dentry) 273int simple_empty(struct dentry *dentry)
268{ 274{
269 struct dentry *child; 275 struct dentry *child;
270 int ret = 0; 276 int ret = 0;
271 277
272 spin_lock(&dcache_lock); 278 spin_lock(&dcache_lock);
273 list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) 279 list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) {
274 if (simple_positive(child)) 280 spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
281 if (simple_positive(child)) {
282 spin_unlock(&child->d_lock);
275 goto out; 283 goto out;
284 }
285 spin_unlock(&child->d_lock);
286 }
276 ret = 1; 287 ret = 1;
277out: 288out:
278 spin_unlock(&dcache_lock); 289 spin_unlock(&dcache_lock);
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
index 895532ac4d98..35e5f5a9ef59 100644
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -174,13 +174,16 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode,
174 list_for_each(p, &inode->i_dentry) { 174 list_for_each(p, &inode->i_dentry) {
175 dentry = list_entry(p, struct dentry, d_alias); 175 dentry = list_entry(p, struct dentry, d_alias);
176 176
177 spin_lock(&dentry->d_lock);
177 if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) { 178 if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
178 mlog(0, "dentry found: %.*s\n", 179 mlog(0, "dentry found: %.*s\n",
179 dentry->d_name.len, dentry->d_name.name); 180 dentry->d_name.len, dentry->d_name.name);
180 181
181 dget_locked(dentry); 182 dget_locked_dlock(dentry);
183 spin_unlock(&dentry->d_lock);
182 break; 184 break;
183 } 185 }
186 spin_unlock(&dentry->d_lock);
184 187
185 dentry = NULL; 188 dentry = NULL;
186 } 189 }
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 1d0bf8fa1922..d1e05b047715 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -14,6 +14,7 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <net/sock.h> 15#include <net/sock.h>
16#include "common.h" 16#include "common.h"
17#include "../../fs/internal.h"
17 18
18/** 19/**
19 * tomoyo_encode: Convert binary string to ascii string. 20 * tomoyo_encode: Convert binary string to ascii string.