aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorNick Piggin <npiggin@kernel.dk>2011-01-07 01:50:06 -0500
committerNick Piggin <npiggin@kernel.dk>2011-01-07 01:50:31 -0500
commit873feea09ebc980cbd3631b767356ce1eee65ec1 (patch)
tree59a8fce9b138086abee7cf845f62ff70a390cf81 /fs/dcache.c
parentceb5bdc2d246f6d81cf61ed70f325308a11821d2 (diff)
fs: dcache per-inode inode alias locking
dcache_inode_lock can be replaced with per-inode locking. Use existing inode->i_lock for this. This is slightly non-trivial because we sometimes need to find the inode from the dentry, which requires d_inode to be stabilised (either with refcount or d_lock). Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c88
1 files changed, 47 insertions, 41 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 9f04e1ba75b7..09ec945f3c98 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -39,8 +39,8 @@
39 39
40/* 40/*
41 * Usage: 41 * Usage:
42 * dcache_inode_lock protects: 42 * dcache->d_inode->i_lock protects:
43 * - i_dentry, d_alias, d_inode 43 * - i_dentry, d_alias, d_inode of aliases
44 * dcache_hash_bucket lock protects: 44 * dcache_hash_bucket lock protects:
45 * - the dcache hash table 45 * - the dcache hash table
46 * s_anon bl list spinlock protects: 46 * s_anon bl list spinlock protects:
@@ -58,7 +58,7 @@
58 * - d_alias, d_inode 58 * - d_alias, d_inode
59 * 59 *
60 * Ordering: 60 * Ordering:
61 * dcache_inode_lock 61 * dentry->d_inode->i_lock
62 * dentry->d_lock 62 * dentry->d_lock
63 * dcache_lru_lock 63 * dcache_lru_lock
64 * dcache_hash_bucket lock 64 * dcache_hash_bucket lock
@@ -78,12 +78,10 @@
78int sysctl_vfs_cache_pressure __read_mostly = 100; 78int sysctl_vfs_cache_pressure __read_mostly = 100;
79EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); 79EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
80 80
81__cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_inode_lock);
82static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lru_lock); 81static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lru_lock);
83__cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); 82__cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
84 83
85EXPORT_SYMBOL(rename_lock); 84EXPORT_SYMBOL(rename_lock);
86EXPORT_SYMBOL(dcache_inode_lock);
87 85
88static struct kmem_cache *dentry_cache __read_mostly; 86static struct kmem_cache *dentry_cache __read_mostly;
89 87
@@ -196,14 +194,14 @@ static inline void dentry_rcuwalk_barrier(struct dentry *dentry)
196 */ 194 */
197static void dentry_iput(struct dentry * dentry) 195static void dentry_iput(struct dentry * dentry)
198 __releases(dentry->d_lock) 196 __releases(dentry->d_lock)
199 __releases(dcache_inode_lock) 197 __releases(dentry->d_inode->i_lock)
200{ 198{
201 struct inode *inode = dentry->d_inode; 199 struct inode *inode = dentry->d_inode;
202 if (inode) { 200 if (inode) {
203 dentry->d_inode = NULL; 201 dentry->d_inode = NULL;
204 list_del_init(&dentry->d_alias); 202 list_del_init(&dentry->d_alias);
205 spin_unlock(&dentry->d_lock); 203 spin_unlock(&dentry->d_lock);
206 spin_unlock(&dcache_inode_lock); 204 spin_unlock(&inode->i_lock);
207 if (!inode->i_nlink) 205 if (!inode->i_nlink)
208 fsnotify_inoderemove(inode); 206 fsnotify_inoderemove(inode);
209 if (dentry->d_op && dentry->d_op->d_iput) 207 if (dentry->d_op && dentry->d_op->d_iput)
@@ -212,7 +210,6 @@ static void dentry_iput(struct dentry * dentry)
212 iput(inode); 210 iput(inode);
213 } else { 211 } else {
214 spin_unlock(&dentry->d_lock); 212 spin_unlock(&dentry->d_lock);
215 spin_unlock(&dcache_inode_lock);
216 } 213 }
217} 214}
218 215
@@ -222,14 +219,14 @@ static void dentry_iput(struct dentry * dentry)
222 */ 219 */
223static void dentry_unlink_inode(struct dentry * dentry) 220static void dentry_unlink_inode(struct dentry * dentry)
224 __releases(dentry->d_lock) 221 __releases(dentry->d_lock)
225 __releases(dcache_inode_lock) 222 __releases(dentry->d_inode->i_lock)
226{ 223{
227 struct inode *inode = dentry->d_inode; 224 struct inode *inode = dentry->d_inode;
228 dentry->d_inode = NULL; 225 dentry->d_inode = NULL;
229 list_del_init(&dentry->d_alias); 226 list_del_init(&dentry->d_alias);
230 dentry_rcuwalk_barrier(dentry); 227 dentry_rcuwalk_barrier(dentry);
231 spin_unlock(&dentry->d_lock); 228 spin_unlock(&dentry->d_lock);
232 spin_unlock(&dcache_inode_lock); 229 spin_unlock(&inode->i_lock);
233 if (!inode->i_nlink) 230 if (!inode->i_nlink)
234 fsnotify_inoderemove(inode); 231 fsnotify_inoderemove(inode);
235 if (dentry->d_op && dentry->d_op->d_iput) 232 if (dentry->d_op && dentry->d_op->d_iput)
@@ -295,7 +292,7 @@ static void dentry_lru_move_tail(struct dentry *dentry)
295static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) 292static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
296 __releases(dentry->d_lock) 293 __releases(dentry->d_lock)
297 __releases(parent->d_lock) 294 __releases(parent->d_lock)
298 __releases(dcache_inode_lock) 295 __releases(dentry->d_inode->i_lock)
299{ 296{
300 dentry->d_parent = NULL; 297 dentry->d_parent = NULL;
301 list_del(&dentry->d_u.d_child); 298 list_del(&dentry->d_u.d_child);
@@ -370,9 +367,11 @@ EXPORT_SYMBOL(d_drop);
370static inline struct dentry *dentry_kill(struct dentry *dentry, int ref) 367static inline struct dentry *dentry_kill(struct dentry *dentry, int ref)
371 __releases(dentry->d_lock) 368 __releases(dentry->d_lock)
372{ 369{
370 struct inode *inode;
373 struct dentry *parent; 371 struct dentry *parent;
374 372
375 if (!spin_trylock(&dcache_inode_lock)) { 373 inode = dentry->d_inode;
374 if (inode && !spin_trylock(&inode->i_lock)) {
376relock: 375relock:
377 spin_unlock(&dentry->d_lock); 376 spin_unlock(&dentry->d_lock);
378 cpu_relax(); 377 cpu_relax();
@@ -383,7 +382,8 @@ relock:
383 else 382 else
384 parent = dentry->d_parent; 383 parent = dentry->d_parent;
385 if (parent && !spin_trylock(&parent->d_lock)) { 384 if (parent && !spin_trylock(&parent->d_lock)) {
386 spin_unlock(&dcache_inode_lock); 385 if (inode)
386 spin_unlock(&inode->i_lock);
387 goto relock; 387 goto relock;
388 } 388 }
389 389
@@ -618,9 +618,9 @@ struct dentry *d_find_alias(struct inode *inode)
618 struct dentry *de = NULL; 618 struct dentry *de = NULL;
619 619
620 if (!list_empty(&inode->i_dentry)) { 620 if (!list_empty(&inode->i_dentry)) {
621 spin_lock(&dcache_inode_lock); 621 spin_lock(&inode->i_lock);
622 de = __d_find_alias(inode, 0); 622 de = __d_find_alias(inode, 0);
623 spin_unlock(&dcache_inode_lock); 623 spin_unlock(&inode->i_lock);
624 } 624 }
625 return de; 625 return de;
626} 626}
@@ -634,20 +634,20 @@ void d_prune_aliases(struct inode *inode)
634{ 634{
635 struct dentry *dentry; 635 struct dentry *dentry;
636restart: 636restart:
637 spin_lock(&dcache_inode_lock); 637 spin_lock(&inode->i_lock);
638 list_for_each_entry(dentry, &inode->i_dentry, d_alias) { 638 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
639 spin_lock(&dentry->d_lock); 639 spin_lock(&dentry->d_lock);
640 if (!dentry->d_count) { 640 if (!dentry->d_count) {
641 __dget_dlock(dentry); 641 __dget_dlock(dentry);
642 __d_drop(dentry); 642 __d_drop(dentry);
643 spin_unlock(&dentry->d_lock); 643 spin_unlock(&dentry->d_lock);
644 spin_unlock(&dcache_inode_lock); 644 spin_unlock(&inode->i_lock);
645 dput(dentry); 645 dput(dentry);
646 goto restart; 646 goto restart;
647 } 647 }
648 spin_unlock(&dentry->d_lock); 648 spin_unlock(&dentry->d_lock);
649 } 649 }
650 spin_unlock(&dcache_inode_lock); 650 spin_unlock(&inode->i_lock);
651} 651}
652EXPORT_SYMBOL(d_prune_aliases); 652EXPORT_SYMBOL(d_prune_aliases);
653 653
@@ -1392,9 +1392,11 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
1392void d_instantiate(struct dentry *entry, struct inode * inode) 1392void d_instantiate(struct dentry *entry, struct inode * inode)
1393{ 1393{
1394 BUG_ON(!list_empty(&entry->d_alias)); 1394 BUG_ON(!list_empty(&entry->d_alias));
1395 spin_lock(&dcache_inode_lock); 1395 if (inode)
1396 spin_lock(&inode->i_lock);
1396 __d_instantiate(entry, inode); 1397 __d_instantiate(entry, inode);
1397 spin_unlock(&dcache_inode_lock); 1398 if (inode)
1399 spin_unlock(&inode->i_lock);
1398 security_d_instantiate(entry, inode); 1400 security_d_instantiate(entry, inode);
1399} 1401}
1400EXPORT_SYMBOL(d_instantiate); 1402EXPORT_SYMBOL(d_instantiate);
@@ -1458,9 +1460,11 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
1458 1460
1459 BUG_ON(!list_empty(&entry->d_alias)); 1461 BUG_ON(!list_empty(&entry->d_alias));
1460 1462
1461 spin_lock(&dcache_inode_lock); 1463 if (inode)
1464 spin_lock(&inode->i_lock);
1462 result = __d_instantiate_unique(entry, inode); 1465 result = __d_instantiate_unique(entry, inode);
1463 spin_unlock(&dcache_inode_lock); 1466 if (inode)
1467 spin_unlock(&inode->i_lock);
1464 1468
1465 if (!result) { 1469 if (!result) {
1466 security_d_instantiate(entry, inode); 1470 security_d_instantiate(entry, inode);
@@ -1542,10 +1546,10 @@ struct dentry *d_obtain_alias(struct inode *inode)
1542 tmp->d_parent = tmp; /* make sure dput doesn't croak */ 1546 tmp->d_parent = tmp; /* make sure dput doesn't croak */
1543 1547
1544 1548
1545 spin_lock(&dcache_inode_lock); 1549 spin_lock(&inode->i_lock);
1546 res = __d_find_alias(inode, 0); 1550 res = __d_find_alias(inode, 0);
1547 if (res) { 1551 if (res) {
1548 spin_unlock(&dcache_inode_lock); 1552 spin_unlock(&inode->i_lock);
1549 dput(tmp); 1553 dput(tmp);
1550 goto out_iput; 1554 goto out_iput;
1551 } 1555 }
@@ -1561,7 +1565,7 @@ struct dentry *d_obtain_alias(struct inode *inode)
1561 hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); 1565 hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon);
1562 __bit_spin_unlock(0, (unsigned long *)&tmp->d_sb->s_anon.first); 1566 __bit_spin_unlock(0, (unsigned long *)&tmp->d_sb->s_anon.first);
1563 spin_unlock(&tmp->d_lock); 1567 spin_unlock(&tmp->d_lock);
1564 spin_unlock(&dcache_inode_lock); 1568 spin_unlock(&inode->i_lock);
1565 1569
1566 return tmp; 1570 return tmp;
1567 1571
@@ -1592,18 +1596,18 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
1592 struct dentry *new = NULL; 1596 struct dentry *new = NULL;
1593 1597
1594 if (inode && S_ISDIR(inode->i_mode)) { 1598 if (inode && S_ISDIR(inode->i_mode)) {
1595 spin_lock(&dcache_inode_lock); 1599 spin_lock(&inode->i_lock);
1596 new = __d_find_alias(inode, 1); 1600 new = __d_find_alias(inode, 1);
1597 if (new) { 1601 if (new) {
1598 BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED)); 1602 BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
1599 spin_unlock(&dcache_inode_lock); 1603 spin_unlock(&inode->i_lock);
1600 security_d_instantiate(new, inode); 1604 security_d_instantiate(new, inode);
1601 d_move(new, dentry); 1605 d_move(new, dentry);
1602 iput(inode); 1606 iput(inode);
1603 } else { 1607 } else {
1604 /* already got dcache_inode_lock, so d_add() by hand */ 1608 /* already taking inode->i_lock, so d_add() by hand */
1605 __d_instantiate(dentry, inode); 1609 __d_instantiate(dentry, inode);
1606 spin_unlock(&dcache_inode_lock); 1610 spin_unlock(&inode->i_lock);
1607 security_d_instantiate(dentry, inode); 1611 security_d_instantiate(dentry, inode);
1608 d_rehash(dentry); 1612 d_rehash(dentry);
1609 } 1613 }
@@ -1676,10 +1680,10 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
1676 * Negative dentry: instantiate it unless the inode is a directory and 1680 * Negative dentry: instantiate it unless the inode is a directory and
1677 * already has a dentry. 1681 * already has a dentry.
1678 */ 1682 */
1679 spin_lock(&dcache_inode_lock); 1683 spin_lock(&inode->i_lock);
1680 if (!S_ISDIR(inode->i_mode) || list_empty(&inode->i_dentry)) { 1684 if (!S_ISDIR(inode->i_mode) || list_empty(&inode->i_dentry)) {
1681 __d_instantiate(found, inode); 1685 __d_instantiate(found, inode);
1682 spin_unlock(&dcache_inode_lock); 1686 spin_unlock(&inode->i_lock);
1683 security_d_instantiate(found, inode); 1687 security_d_instantiate(found, inode);
1684 return found; 1688 return found;
1685 } 1689 }
@@ -1690,7 +1694,7 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
1690 */ 1694 */
1691 new = list_entry(inode->i_dentry.next, struct dentry, d_alias); 1695 new = list_entry(inode->i_dentry.next, struct dentry, d_alias);
1692 __dget(new); 1696 __dget(new);
1693 spin_unlock(&dcache_inode_lock); 1697 spin_unlock(&inode->i_lock);
1694 security_d_instantiate(found, inode); 1698 security_d_instantiate(found, inode);
1695 d_move(new, found); 1699 d_move(new, found);
1696 iput(inode); 1700 iput(inode);
@@ -2004,15 +2008,17 @@ EXPORT_SYMBOL(d_validate);
2004 2008
2005void d_delete(struct dentry * dentry) 2009void d_delete(struct dentry * dentry)
2006{ 2010{
2011 struct inode *inode;
2007 int isdir = 0; 2012 int isdir = 0;
2008 /* 2013 /*
2009 * Are we the only user? 2014 * Are we the only user?
2010 */ 2015 */
2011again: 2016again:
2012 spin_lock(&dentry->d_lock); 2017 spin_lock(&dentry->d_lock);
2013 isdir = S_ISDIR(dentry->d_inode->i_mode); 2018 inode = dentry->d_inode;
2019 isdir = S_ISDIR(inode->i_mode);
2014 if (dentry->d_count == 1) { 2020 if (dentry->d_count == 1) {
2015 if (!spin_trylock(&dcache_inode_lock)) { 2021 if (inode && !spin_trylock(&inode->i_lock)) {
2016 spin_unlock(&dentry->d_lock); 2022 spin_unlock(&dentry->d_lock);
2017 cpu_relax(); 2023 cpu_relax();
2018 goto again; 2024 goto again;
@@ -2266,13 +2272,13 @@ struct dentry *d_ancestor(struct dentry *p1, struct dentry *p2)
2266 * This helper attempts to cope with remotely renamed directories 2272 * This helper attempts to cope with remotely renamed directories
2267 * 2273 *
2268 * It assumes that the caller is already holding 2274 * It assumes that the caller is already holding
2269 * dentry->d_parent->d_inode->i_mutex and the dcache_inode_lock 2275 * dentry->d_parent->d_inode->i_mutex and the inode->i_lock
2270 * 2276 *
2271 * Note: If ever the locking in lock_rename() changes, then please 2277 * Note: If ever the locking in lock_rename() changes, then please
2272 * remember to update this too... 2278 * remember to update this too...
2273 */ 2279 */
2274static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias) 2280static struct dentry *__d_unalias(struct inode *inode,
2275 __releases(dcache_inode_lock) 2281 struct dentry *dentry, struct dentry *alias)
2276{ 2282{
2277 struct mutex *m1 = NULL, *m2 = NULL; 2283 struct mutex *m1 = NULL, *m2 = NULL;
2278 struct dentry *ret; 2284 struct dentry *ret;
@@ -2298,7 +2304,7 @@ out_unalias:
2298 d_move(alias, dentry); 2304 d_move(alias, dentry);
2299 ret = alias; 2305 ret = alias;
2300out_err: 2306out_err:
2301 spin_unlock(&dcache_inode_lock); 2307 spin_unlock(&inode->i_lock);
2302 if (m2) 2308 if (m2)
2303 mutex_unlock(m2); 2309 mutex_unlock(m2);
2304 if (m1) 2310 if (m1)
@@ -2371,7 +2377,7 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
2371 goto out_nolock; 2377 goto out_nolock;
2372 } 2378 }
2373 2379
2374 spin_lock(&dcache_inode_lock); 2380 spin_lock(&inode->i_lock);
2375 2381
2376 if (S_ISDIR(inode->i_mode)) { 2382 if (S_ISDIR(inode->i_mode)) {
2377 struct dentry *alias; 2383 struct dentry *alias;
@@ -2388,7 +2394,7 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
2388 goto found; 2394 goto found;
2389 } 2395 }
2390 /* Nope, but we must(!) avoid directory aliasing */ 2396 /* Nope, but we must(!) avoid directory aliasing */
2391 actual = __d_unalias(dentry, alias); 2397 actual = __d_unalias(inode, dentry, alias);
2392 if (IS_ERR(actual)) 2398 if (IS_ERR(actual))
2393 dput(alias); 2399 dput(alias);
2394 goto out_nolock; 2400 goto out_nolock;
@@ -2406,7 +2412,7 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
2406found: 2412found:
2407 _d_rehash(actual); 2413 _d_rehash(actual);
2408 spin_unlock(&actual->d_lock); 2414 spin_unlock(&actual->d_lock);
2409 spin_unlock(&dcache_inode_lock); 2415 spin_unlock(&inode->i_lock);
2410out_nolock: 2416out_nolock:
2411 if (actual == dentry) { 2417 if (actual == dentry) {
2412 security_d_instantiate(dentry, inode); 2418 security_d_instantiate(dentry, inode);