aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Piggin <npiggin@kernel.dk>2011-01-07 01:49:35 -0500
committerNick Piggin <npiggin@kernel.dk>2011-01-07 01:50:22 -0500
commitb23fb0a60379a95e10c671f646b259ea2558421e (patch)
tree7c3644b91241d32fda502a7be0b78e4c225f8091
parent2fd6b7f50797f2e993eea59e0a0b8c6399c811dc (diff)
fs: scale inode alias list
Add a new lock, dcache_inode_lock, to protect the inode's i_dentry list from concurrent modification. d_alias is also protected by d_lock. Signed-off-by: Nick Piggin <npiggin@kernel.dk>
-rw-r--r--fs/9p/vfs_inode.c2
-rw-r--r--fs/affs/amigaffs.c2
-rw-r--r--fs/cifs/inode.c3
-rw-r--r--fs/dcache.c66
-rw-r--r--fs/exportfs/expfs.c4
-rw-r--r--fs/nfs/getroot.c4
-rw-r--r--fs/notify/fsnotify.c2
-rw-r--r--fs/ocfs2/dcache.c3
-rw-r--r--include/linux/dcache.h1
9 files changed, 78 insertions, 9 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 34bf71b56542..47dfd5d29a6b 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -271,9 +271,11 @@ static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
271 struct dentry *dentry; 271 struct dentry *dentry;
272 272
273 spin_lock(&dcache_lock); 273 spin_lock(&dcache_lock);
274 spin_lock(&dcache_inode_lock);
274 /* Directory should have only one entry. */ 275 /* Directory should have only one entry. */
275 BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry)); 276 BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry));
276 dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias); 277 dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
278 spin_unlock(&dcache_inode_lock);
277 spin_unlock(&dcache_lock); 279 spin_unlock(&dcache_lock);
278 return dentry; 280 return dentry;
279} 281}
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c
index 7d0f0a30f7a3..2321cc92d44f 100644
--- a/fs/affs/amigaffs.c
+++ b/fs/affs/amigaffs.c
@@ -129,6 +129,7 @@ affs_fix_dcache(struct dentry *dentry, u32 entry_ino)
129 struct list_head *head, *next; 129 struct list_head *head, *next;
130 130
131 spin_lock(&dcache_lock); 131 spin_lock(&dcache_lock);
132 spin_lock(&dcache_inode_lock);
132 head = &inode->i_dentry; 133 head = &inode->i_dentry;
133 next = head->next; 134 next = head->next;
134 while (next != head) { 135 while (next != head) {
@@ -139,6 +140,7 @@ affs_fix_dcache(struct dentry *dentry, u32 entry_ino)
139 } 140 }
140 next = next->next; 141 next = next->next;
141 } 142 }
143 spin_unlock(&dcache_inode_lock);
142 spin_unlock(&dcache_lock); 144 spin_unlock(&dcache_lock);
143} 145}
144 146
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 589f3e3f6e00..003698365ece 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -810,12 +810,15 @@ inode_has_hashed_dentries(struct inode *inode)
810 struct dentry *dentry; 810 struct dentry *dentry;
811 811
812 spin_lock(&dcache_lock); 812 spin_lock(&dcache_lock);
813 spin_lock(&dcache_inode_lock);
813 list_for_each_entry(dentry, &inode->i_dentry, d_alias) { 814 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
814 if (!d_unhashed(dentry) || IS_ROOT(dentry)) { 815 if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
816 spin_unlock(&dcache_inode_lock);
815 spin_unlock(&dcache_lock); 817 spin_unlock(&dcache_lock);
816 return true; 818 return true;
817 } 819 }
818 } 820 }
821 spin_unlock(&dcache_inode_lock);
819 spin_unlock(&dcache_lock); 822 spin_unlock(&dcache_lock);
820 return false; 823 return false;
821} 824}
diff --git a/fs/dcache.c b/fs/dcache.c
index a661247a20d5..de38680ee0ed 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -37,6 +37,8 @@
37 37
38/* 38/*
39 * Usage: 39 * Usage:
40 * dcache_inode_lock protects:
41 * - i_dentry, d_alias, d_inode
40 * dcache_hash_lock protects: 42 * dcache_hash_lock protects:
41 * - the dcache hash table, s_anon lists 43 * - the dcache hash table, s_anon lists
42 * dcache_lru_lock protects: 44 * dcache_lru_lock protects:
@@ -49,12 +51,14 @@
49 * - d_unhashed() 51 * - d_unhashed()
50 * - d_parent and d_subdirs 52 * - d_parent and d_subdirs
51 * - childrens' d_child and d_parent 53 * - childrens' d_child and d_parent
54 * - d_alias, d_inode
52 * 55 *
53 * Ordering: 56 * Ordering:
54 * dcache_lock 57 * dcache_lock
55 * dentry->d_lock 58 * dcache_inode_lock
56 * dcache_lru_lock 59 * dentry->d_lock
57 * dcache_hash_lock 60 * dcache_lru_lock
61 * dcache_hash_lock
58 * 62 *
59 * If there is an ancestor relationship: 63 * If there is an ancestor relationship:
60 * dentry->d_parent->...->d_parent->d_lock 64 * dentry->d_parent->...->d_parent->d_lock
@@ -70,11 +74,13 @@
70int sysctl_vfs_cache_pressure __read_mostly = 100; 74int sysctl_vfs_cache_pressure __read_mostly = 100;
71EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); 75EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
72 76
77__cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_inode_lock);
73static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_hash_lock); 78static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_hash_lock);
74static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lru_lock); 79static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lru_lock);
75__cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock); 80__cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock);
76__cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); 81__cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
77 82
83EXPORT_SYMBOL(dcache_inode_lock);
78EXPORT_SYMBOL(dcache_lock); 84EXPORT_SYMBOL(dcache_lock);
79 85
80static struct kmem_cache *dentry_cache __read_mostly; 86static struct kmem_cache *dentry_cache __read_mostly;
@@ -154,6 +160,7 @@ static void d_free(struct dentry *dentry)
154 */ 160 */
155static void dentry_iput(struct dentry * dentry) 161static void dentry_iput(struct dentry * dentry)
156 __releases(dentry->d_lock) 162 __releases(dentry->d_lock)
163 __releases(dcache_inode_lock)
157 __releases(dcache_lock) 164 __releases(dcache_lock)
158{ 165{
159 struct inode *inode = dentry->d_inode; 166 struct inode *inode = dentry->d_inode;
@@ -161,6 +168,7 @@ static void dentry_iput(struct dentry * dentry)
161 dentry->d_inode = NULL; 168 dentry->d_inode = NULL;
162 list_del_init(&dentry->d_alias); 169 list_del_init(&dentry->d_alias);
163 spin_unlock(&dentry->d_lock); 170 spin_unlock(&dentry->d_lock);
171 spin_unlock(&dcache_inode_lock);
164 spin_unlock(&dcache_lock); 172 spin_unlock(&dcache_lock);
165 if (!inode->i_nlink) 173 if (!inode->i_nlink)
166 fsnotify_inoderemove(inode); 174 fsnotify_inoderemove(inode);
@@ -170,6 +178,7 @@ static void dentry_iput(struct dentry * dentry)
170 iput(inode); 178 iput(inode);
171 } else { 179 } else {
172 spin_unlock(&dentry->d_lock); 180 spin_unlock(&dentry->d_lock);
181 spin_unlock(&dcache_inode_lock);
173 spin_unlock(&dcache_lock); 182 spin_unlock(&dcache_lock);
174 } 183 }
175} 184}
@@ -231,6 +240,7 @@ static void dentry_lru_move_tail(struct dentry *dentry)
231static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) 240static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
232 __releases(dentry->d_lock) 241 __releases(dentry->d_lock)
233 __releases(parent->d_lock) 242 __releases(parent->d_lock)
243 __releases(dcache_inode_lock)
234 __releases(dcache_lock) 244 __releases(dcache_lock)
235{ 245{
236 list_del(&dentry->d_u.d_child); 246 list_del(&dentry->d_u.d_child);
@@ -332,13 +342,18 @@ repeat:
332 * want to reduce dcache_lock anyway so this will 342 * want to reduce dcache_lock anyway so this will
333 * get improved. 343 * get improved.
334 */ 344 */
345drop1:
335 spin_unlock(&dentry->d_lock); 346 spin_unlock(&dentry->d_lock);
336 goto repeat; 347 goto repeat;
337 } 348 }
338 if (parent && !spin_trylock(&parent->d_lock)) { 349 if (!spin_trylock(&dcache_inode_lock)) {
339 spin_unlock(&dentry->d_lock); 350drop2:
340 spin_unlock(&dcache_lock); 351 spin_unlock(&dcache_lock);
341 goto repeat; 352 goto drop1;
353 }
354 if (parent && !spin_trylock(&parent->d_lock)) {
355 spin_unlock(&dcache_inode_lock);
356 goto drop2;
342 } 357 }
343 } 358 }
344 dentry->d_count--; 359 dentry->d_count--;
@@ -369,6 +384,7 @@ repeat:
369 spin_unlock(&dentry->d_lock); 384 spin_unlock(&dentry->d_lock);
370 if (parent) 385 if (parent)
371 spin_unlock(&parent->d_lock); 386 spin_unlock(&parent->d_lock);
387 spin_unlock(&dcache_inode_lock);
372 spin_unlock(&dcache_lock); 388 spin_unlock(&dcache_lock);
373 return; 389 return;
374 390
@@ -558,7 +574,9 @@ struct dentry *d_find_alias(struct inode *inode)
558 574
559 if (!list_empty(&inode->i_dentry)) { 575 if (!list_empty(&inode->i_dentry)) {
560 spin_lock(&dcache_lock); 576 spin_lock(&dcache_lock);
577 spin_lock(&dcache_inode_lock);
561 de = __d_find_alias(inode, 0); 578 de = __d_find_alias(inode, 0);
579 spin_unlock(&dcache_inode_lock);
562 spin_unlock(&dcache_lock); 580 spin_unlock(&dcache_lock);
563 } 581 }
564 return de; 582 return de;
@@ -574,18 +592,21 @@ void d_prune_aliases(struct inode *inode)
574 struct dentry *dentry; 592 struct dentry *dentry;
575restart: 593restart:
576 spin_lock(&dcache_lock); 594 spin_lock(&dcache_lock);
595 spin_lock(&dcache_inode_lock);
577 list_for_each_entry(dentry, &inode->i_dentry, d_alias) { 596 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
578 spin_lock(&dentry->d_lock); 597 spin_lock(&dentry->d_lock);
579 if (!dentry->d_count) { 598 if (!dentry->d_count) {
580 __dget_locked_dlock(dentry); 599 __dget_locked_dlock(dentry);
581 __d_drop(dentry); 600 __d_drop(dentry);
582 spin_unlock(&dentry->d_lock); 601 spin_unlock(&dentry->d_lock);
602 spin_unlock(&dcache_inode_lock);
583 spin_unlock(&dcache_lock); 603 spin_unlock(&dcache_lock);
584 dput(dentry); 604 dput(dentry);
585 goto restart; 605 goto restart;
586 } 606 }
587 spin_unlock(&dentry->d_lock); 607 spin_unlock(&dentry->d_lock);
588 } 608 }
609 spin_unlock(&dcache_inode_lock);
589 spin_unlock(&dcache_lock); 610 spin_unlock(&dcache_lock);
590} 611}
591EXPORT_SYMBOL(d_prune_aliases); 612EXPORT_SYMBOL(d_prune_aliases);
@@ -601,6 +622,7 @@ EXPORT_SYMBOL(d_prune_aliases);
601static void prune_one_dentry(struct dentry *dentry, struct dentry *parent) 622static void prune_one_dentry(struct dentry *dentry, struct dentry *parent)
602 __releases(dentry->d_lock) 623 __releases(dentry->d_lock)
603 __releases(parent->d_lock) 624 __releases(parent->d_lock)
625 __releases(dcache_inode_lock)
604 __releases(dcache_lock) 626 __releases(dcache_lock)
605{ 627{
606 __d_drop(dentry); 628 __d_drop(dentry);
@@ -612,6 +634,7 @@ static void prune_one_dentry(struct dentry *dentry, struct dentry *parent)
612 */ 634 */
613 while (dentry) { 635 while (dentry) {
614 spin_lock(&dcache_lock); 636 spin_lock(&dcache_lock);
637 spin_lock(&dcache_inode_lock);
615again: 638again:
616 spin_lock(&dentry->d_lock); 639 spin_lock(&dentry->d_lock);
617 if (IS_ROOT(dentry)) 640 if (IS_ROOT(dentry))
@@ -627,6 +650,7 @@ again:
627 if (parent) 650 if (parent)
628 spin_unlock(&parent->d_lock); 651 spin_unlock(&parent->d_lock);
629 spin_unlock(&dentry->d_lock); 652 spin_unlock(&dentry->d_lock);
653 spin_unlock(&dcache_inode_lock);
630 spin_unlock(&dcache_lock); 654 spin_unlock(&dcache_lock);
631 return; 655 return;
632 } 656 }
@@ -676,8 +700,9 @@ relock:
676 spin_unlock(&dcache_lru_lock); 700 spin_unlock(&dcache_lru_lock);
677 701
678 prune_one_dentry(dentry, parent); 702 prune_one_dentry(dentry, parent);
679 /* dcache_lock and dentry->d_lock dropped */ 703 /* dcache_lock, dcache_inode_lock and dentry->d_lock dropped */
680 spin_lock(&dcache_lock); 704 spin_lock(&dcache_lock);
705 spin_lock(&dcache_inode_lock);
681 spin_lock(&dcache_lru_lock); 706 spin_lock(&dcache_lru_lock);
682 } 707 }
683} 708}
@@ -699,6 +724,7 @@ static void __shrink_dcache_sb(struct super_block *sb, int *count, int flags)
699 int cnt = *count; 724 int cnt = *count;
700 725
701 spin_lock(&dcache_lock); 726 spin_lock(&dcache_lock);
727 spin_lock(&dcache_inode_lock);
702relock: 728relock:
703 spin_lock(&dcache_lru_lock); 729 spin_lock(&dcache_lru_lock);
704 while (!list_empty(&sb->s_dentry_lru)) { 730 while (!list_empty(&sb->s_dentry_lru)) {
@@ -737,8 +763,8 @@ relock:
737 if (!list_empty(&referenced)) 763 if (!list_empty(&referenced))
738 list_splice(&referenced, &sb->s_dentry_lru); 764 list_splice(&referenced, &sb->s_dentry_lru);
739 spin_unlock(&dcache_lru_lock); 765 spin_unlock(&dcache_lru_lock);
766 spin_unlock(&dcache_inode_lock);
740 spin_unlock(&dcache_lock); 767 spin_unlock(&dcache_lock);
741
742} 768}
743 769
744/** 770/**
@@ -832,12 +858,14 @@ void shrink_dcache_sb(struct super_block *sb)
832 LIST_HEAD(tmp); 858 LIST_HEAD(tmp);
833 859
834 spin_lock(&dcache_lock); 860 spin_lock(&dcache_lock);
861 spin_lock(&dcache_inode_lock);
835 spin_lock(&dcache_lru_lock); 862 spin_lock(&dcache_lru_lock);
836 while (!list_empty(&sb->s_dentry_lru)) { 863 while (!list_empty(&sb->s_dentry_lru)) {
837 list_splice_init(&sb->s_dentry_lru, &tmp); 864 list_splice_init(&sb->s_dentry_lru, &tmp);
838 shrink_dentry_list(&tmp); 865 shrink_dentry_list(&tmp);
839 } 866 }
840 spin_unlock(&dcache_lru_lock); 867 spin_unlock(&dcache_lru_lock);
868 spin_unlock(&dcache_inode_lock);
841 spin_unlock(&dcache_lock); 869 spin_unlock(&dcache_lock);
842} 870}
843EXPORT_SYMBOL(shrink_dcache_sb); 871EXPORT_SYMBOL(shrink_dcache_sb);
@@ -1255,9 +1283,11 @@ EXPORT_SYMBOL(d_alloc_name);
1255/* the caller must hold dcache_lock */ 1283/* the caller must hold dcache_lock */
1256static void __d_instantiate(struct dentry *dentry, struct inode *inode) 1284static void __d_instantiate(struct dentry *dentry, struct inode *inode)
1257{ 1285{
1286 spin_lock(&dentry->d_lock);
1258 if (inode) 1287 if (inode)
1259 list_add(&dentry->d_alias, &inode->i_dentry); 1288 list_add(&dentry->d_alias, &inode->i_dentry);
1260 dentry->d_inode = inode; 1289 dentry->d_inode = inode;
1290 spin_unlock(&dentry->d_lock);
1261 fsnotify_d_instantiate(dentry, inode); 1291 fsnotify_d_instantiate(dentry, inode);
1262} 1292}
1263 1293
@@ -1280,7 +1310,9 @@ void d_instantiate(struct dentry *entry, struct inode * inode)
1280{ 1310{
1281 BUG_ON(!list_empty(&entry->d_alias)); 1311 BUG_ON(!list_empty(&entry->d_alias));
1282 spin_lock(&dcache_lock); 1312 spin_lock(&dcache_lock);
1313 spin_lock(&dcache_inode_lock);
1283 __d_instantiate(entry, inode); 1314 __d_instantiate(entry, inode);
1315 spin_unlock(&dcache_inode_lock);
1284 spin_unlock(&dcache_lock); 1316 spin_unlock(&dcache_lock);
1285 security_d_instantiate(entry, inode); 1317 security_d_instantiate(entry, inode);
1286} 1318}
@@ -1341,7 +1373,9 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
1341 BUG_ON(!list_empty(&entry->d_alias)); 1373 BUG_ON(!list_empty(&entry->d_alias));
1342 1374
1343 spin_lock(&dcache_lock); 1375 spin_lock(&dcache_lock);
1376 spin_lock(&dcache_inode_lock);
1344 result = __d_instantiate_unique(entry, inode); 1377 result = __d_instantiate_unique(entry, inode);
1378 spin_unlock(&dcache_inode_lock);
1345 spin_unlock(&dcache_lock); 1379 spin_unlock(&dcache_lock);
1346 1380
1347 if (!result) { 1381 if (!result) {
@@ -1432,8 +1466,10 @@ struct dentry *d_obtain_alias(struct inode *inode)
1432 tmp->d_parent = tmp; /* make sure dput doesn't croak */ 1466 tmp->d_parent = tmp; /* make sure dput doesn't croak */
1433 1467
1434 spin_lock(&dcache_lock); 1468 spin_lock(&dcache_lock);
1469 spin_lock(&dcache_inode_lock);
1435 res = __d_find_alias(inode, 0); 1470 res = __d_find_alias(inode, 0);
1436 if (res) { 1471 if (res) {
1472 spin_unlock(&dcache_inode_lock);
1437 spin_unlock(&dcache_lock); 1473 spin_unlock(&dcache_lock);
1438 dput(tmp); 1474 dput(tmp);
1439 goto out_iput; 1475 goto out_iput;
@@ -1450,6 +1486,7 @@ struct dentry *d_obtain_alias(struct inode *inode)
1450 hlist_add_head(&tmp->d_hash, &inode->i_sb->s_anon); 1486 hlist_add_head(&tmp->d_hash, &inode->i_sb->s_anon);
1451 spin_unlock(&dcache_hash_lock); 1487 spin_unlock(&dcache_hash_lock);
1452 spin_unlock(&tmp->d_lock); 1488 spin_unlock(&tmp->d_lock);
1489 spin_unlock(&dcache_inode_lock);
1453 1490
1454 spin_unlock(&dcache_lock); 1491 spin_unlock(&dcache_lock);
1455 return tmp; 1492 return tmp;
@@ -1482,9 +1519,11 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
1482 1519
1483 if (inode && S_ISDIR(inode->i_mode)) { 1520 if (inode && S_ISDIR(inode->i_mode)) {
1484 spin_lock(&dcache_lock); 1521 spin_lock(&dcache_lock);
1522 spin_lock(&dcache_inode_lock);
1485 new = __d_find_alias(inode, 1); 1523 new = __d_find_alias(inode, 1);
1486 if (new) { 1524 if (new) {
1487 BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED)); 1525 BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
1526 spin_unlock(&dcache_inode_lock);
1488 spin_unlock(&dcache_lock); 1527 spin_unlock(&dcache_lock);
1489 security_d_instantiate(new, inode); 1528 security_d_instantiate(new, inode);
1490 d_move(new, dentry); 1529 d_move(new, dentry);
@@ -1492,6 +1531,7 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
1492 } else { 1531 } else {
1493 /* already taking dcache_lock, so d_add() by hand */ 1532 /* already taking dcache_lock, so d_add() by hand */
1494 __d_instantiate(dentry, inode); 1533 __d_instantiate(dentry, inode);
1534 spin_unlock(&dcache_inode_lock);
1495 spin_unlock(&dcache_lock); 1535 spin_unlock(&dcache_lock);
1496 security_d_instantiate(dentry, inode); 1536 security_d_instantiate(dentry, inode);
1497 d_rehash(dentry); 1537 d_rehash(dentry);
@@ -1566,8 +1606,10 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
1566 * already has a dentry. 1606 * already has a dentry.
1567 */ 1607 */
1568 spin_lock(&dcache_lock); 1608 spin_lock(&dcache_lock);
1609 spin_lock(&dcache_inode_lock);
1569 if (!S_ISDIR(inode->i_mode) || list_empty(&inode->i_dentry)) { 1610 if (!S_ISDIR(inode->i_mode) || list_empty(&inode->i_dentry)) {
1570 __d_instantiate(found, inode); 1611 __d_instantiate(found, inode);
1612 spin_unlock(&dcache_inode_lock);
1571 spin_unlock(&dcache_lock); 1613 spin_unlock(&dcache_lock);
1572 security_d_instantiate(found, inode); 1614 security_d_instantiate(found, inode);
1573 return found; 1615 return found;
@@ -1579,6 +1621,7 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
1579 */ 1621 */
1580 new = list_entry(inode->i_dentry.next, struct dentry, d_alias); 1622 new = list_entry(inode->i_dentry.next, struct dentry, d_alias);
1581 dget_locked(new); 1623 dget_locked(new);
1624 spin_unlock(&dcache_inode_lock);
1582 spin_unlock(&dcache_lock); 1625 spin_unlock(&dcache_lock);
1583 security_d_instantiate(found, inode); 1626 security_d_instantiate(found, inode);
1584 d_move(new, found); 1627 d_move(new, found);
@@ -1797,6 +1840,7 @@ void d_delete(struct dentry * dentry)
1797 * Are we the only user? 1840 * Are we the only user?
1798 */ 1841 */
1799 spin_lock(&dcache_lock); 1842 spin_lock(&dcache_lock);
1843 spin_lock(&dcache_inode_lock);
1800 spin_lock(&dentry->d_lock); 1844 spin_lock(&dentry->d_lock);
1801 isdir = S_ISDIR(dentry->d_inode->i_mode); 1845 isdir = S_ISDIR(dentry->d_inode->i_mode);
1802 if (dentry->d_count == 1) { 1846 if (dentry->d_count == 1) {
@@ -1810,6 +1854,7 @@ void d_delete(struct dentry * dentry)
1810 __d_drop(dentry); 1854 __d_drop(dentry);
1811 1855
1812 spin_unlock(&dentry->d_lock); 1856 spin_unlock(&dentry->d_lock);
1857 spin_unlock(&dcache_inode_lock);
1813 spin_unlock(&dcache_lock); 1858 spin_unlock(&dcache_lock);
1814 1859
1815 fsnotify_nameremove(dentry, isdir); 1860 fsnotify_nameremove(dentry, isdir);
@@ -2067,6 +2112,7 @@ struct dentry *d_ancestor(struct dentry *p1, struct dentry *p2)
2067 */ 2112 */
2068static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias) 2113static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
2069 __releases(dcache_lock) 2114 __releases(dcache_lock)
2115 __releases(dcache_inode_lock)
2070{ 2116{
2071 struct mutex *m1 = NULL, *m2 = NULL; 2117 struct mutex *m1 = NULL, *m2 = NULL;
2072 struct dentry *ret; 2118 struct dentry *ret;
@@ -2092,6 +2138,7 @@ out_unalias:
2092 d_move_locked(alias, dentry); 2138 d_move_locked(alias, dentry);
2093 ret = alias; 2139 ret = alias;
2094out_err: 2140out_err:
2141 spin_unlock(&dcache_inode_lock);
2095 spin_unlock(&dcache_lock); 2142 spin_unlock(&dcache_lock);
2096 if (m2) 2143 if (m2)
2097 mutex_unlock(m2); 2144 mutex_unlock(m2);
@@ -2153,6 +2200,7 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
2153 BUG_ON(!d_unhashed(dentry)); 2200 BUG_ON(!d_unhashed(dentry));
2154 2201
2155 spin_lock(&dcache_lock); 2202 spin_lock(&dcache_lock);
2203 spin_lock(&dcache_inode_lock);
2156 2204
2157 if (!inode) { 2205 if (!inode) {
2158 actual = dentry; 2206 actual = dentry;
@@ -2196,6 +2244,7 @@ found:
2196 _d_rehash(actual); 2244 _d_rehash(actual);
2197 spin_unlock(&dcache_hash_lock); 2245 spin_unlock(&dcache_hash_lock);
2198 spin_unlock(&actual->d_lock); 2246 spin_unlock(&actual->d_lock);
2247 spin_unlock(&dcache_inode_lock);
2199 spin_unlock(&dcache_lock); 2248 spin_unlock(&dcache_lock);
2200out_nolock: 2249out_nolock:
2201 if (actual == dentry) { 2250 if (actual == dentry) {
@@ -2207,6 +2256,7 @@ out_nolock:
2207 return actual; 2256 return actual;
2208 2257
2209shouldnt_be_hashed: 2258shouldnt_be_hashed:
2259 spin_unlock(&dcache_inode_lock);
2210 spin_unlock(&dcache_lock); 2260 spin_unlock(&dcache_lock);
2211 BUG(); 2261 BUG();
2212} 2262}
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 51b304056f10..84b8c460a781 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -48,8 +48,10 @@ find_acceptable_alias(struct dentry *result,
48 return result; 48 return result;
49 49
50 spin_lock(&dcache_lock); 50 spin_lock(&dcache_lock);
51 spin_lock(&dcache_inode_lock);
51 list_for_each_entry(dentry, &result->d_inode->i_dentry, d_alias) { 52 list_for_each_entry(dentry, &result->d_inode->i_dentry, d_alias) {
52 dget_locked(dentry); 53 dget_locked(dentry);
54 spin_unlock(&dcache_inode_lock);
53 spin_unlock(&dcache_lock); 55 spin_unlock(&dcache_lock);
54 if (toput) 56 if (toput)
55 dput(toput); 57 dput(toput);
@@ -58,8 +60,10 @@ find_acceptable_alias(struct dentry *result,
58 return dentry; 60 return dentry;
59 } 61 }
60 spin_lock(&dcache_lock); 62 spin_lock(&dcache_lock);
63 spin_lock(&dcache_inode_lock);
61 toput = dentry; 64 toput = dentry;
62 } 65 }
66 spin_unlock(&dcache_inode_lock);
63 spin_unlock(&dcache_lock); 67 spin_unlock(&dcache_lock);
64 68
65 if (toput) 69 if (toput)
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index ac7b814ce162..850f67d5f0ac 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -64,7 +64,11 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i
64 * Oops, since the test for IS_ROOT() will fail. 64 * Oops, since the test for IS_ROOT() will fail.
65 */ 65 */
66 spin_lock(&dcache_lock); 66 spin_lock(&dcache_lock);
67 spin_lock(&dcache_inode_lock);
68 spin_lock(&sb->s_root->d_lock);
67 list_del_init(&sb->s_root->d_alias); 69 list_del_init(&sb->s_root->d_alias);
70 spin_unlock(&sb->s_root->d_lock);
71 spin_unlock(&dcache_inode_lock);
68 spin_unlock(&dcache_lock); 72 spin_unlock(&dcache_lock);
69 } 73 }
70 return 0; 74 return 0;
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index aa4f25e803f6..ae769fc9b66c 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -60,6 +60,7 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
60 watched = fsnotify_inode_watches_children(inode); 60 watched = fsnotify_inode_watches_children(inode);
61 61
62 spin_lock(&dcache_lock); 62 spin_lock(&dcache_lock);
63 spin_lock(&dcache_inode_lock);
63 /* run all of the dentries associated with this inode. Since this is a 64 /* run all of the dentries associated with this inode. Since this is a
64 * directory, there damn well better only be one item on this list */ 65 * directory, there damn well better only be one item on this list */
65 list_for_each_entry(alias, &inode->i_dentry, d_alias) { 66 list_for_each_entry(alias, &inode->i_dentry, d_alias) {
@@ -82,6 +83,7 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
82 } 83 }
83 spin_unlock(&alias->d_lock); 84 spin_unlock(&alias->d_lock);
84 } 85 }
86 spin_unlock(&dcache_inode_lock);
85 spin_unlock(&dcache_lock); 87 spin_unlock(&dcache_lock);
86} 88}
87 89
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
index 35e5f5a9ef59..c31b5c647ac7 100644
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -170,7 +170,7 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode,
170 struct dentry *dentry = NULL; 170 struct dentry *dentry = NULL;
171 171
172 spin_lock(&dcache_lock); 172 spin_lock(&dcache_lock);
173 173 spin_lock(&dcache_inode_lock);
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
@@ -188,6 +188,7 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode,
188 dentry = NULL; 188 dentry = NULL;
189 } 189 }
190 190
191 spin_unlock(&dcache_inode_lock);
191 spin_unlock(&dcache_lock); 192 spin_unlock(&dcache_lock);
192 193
193 return dentry; 194 return dentry;
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index ddf4f55624f7..bda5ec0b077d 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -181,6 +181,7 @@ struct dentry_operations {
181 181
182#define DCACHE_CANT_MOUNT 0x0100 182#define DCACHE_CANT_MOUNT 0x0100
183 183
184extern spinlock_t dcache_inode_lock;
184extern spinlock_t dcache_lock; 185extern spinlock_t dcache_lock;
185extern seqlock_t rename_lock; 186extern seqlock_t rename_lock;
186 187