Commit 873feea09ebc980cbd3631b767356ce1eee65ec1

Authored by Nick Piggin
1 parent ceb5bdc2d2

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>

Showing 9 changed files with 67 additions and 60 deletions Side-by-side Diff

... ... @@ -277,11 +277,11 @@
277 277 {
278 278 struct dentry *dentry;
279 279  
280   - spin_lock(&dcache_inode_lock);
  280 + spin_lock(&inode->i_lock);
281 281 /* Directory should have only one entry. */
282 282 BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry));
283 283 dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
284   - spin_unlock(&dcache_inode_lock);
  284 + spin_unlock(&inode->i_lock);
285 285 return dentry;
286 286 }
287 287  
... ... @@ -128,7 +128,7 @@
128 128 void *data = dentry->d_fsdata;
129 129 struct list_head *head, *next;
130 130  
131   - spin_lock(&dcache_inode_lock);
  131 + spin_lock(&inode->i_lock);
132 132 head = &inode->i_dentry;
133 133 next = head->next;
134 134 while (next != head) {
... ... @@ -139,7 +139,7 @@
139 139 }
140 140 next = next->next;
141 141 }
142   - spin_unlock(&dcache_inode_lock);
  142 + spin_unlock(&inode->i_lock);
143 143 }
144 144  
145 145  
... ... @@ -809,14 +809,14 @@
809 809 {
810 810 struct dentry *dentry;
811 811  
812   - spin_lock(&dcache_inode_lock);
  812 + spin_lock(&inode->i_lock);
813 813 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
814 814 if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
815   - spin_unlock(&dcache_inode_lock);
  815 + spin_unlock(&inode->i_lock);
816 816 return true;
817 817 }
818 818 }
819   - spin_unlock(&dcache_inode_lock);
  819 + spin_unlock(&inode->i_lock);
820 820 return false;
821 821 }
822 822  
... ... @@ -39,8 +39,8 @@
39 39  
40 40 /*
41 41 * Usage:
42   - * dcache_inode_lock protects:
43   - * - i_dentry, d_alias, d_inode
  42 + * dcache->d_inode->i_lock protects:
  43 + * - i_dentry, d_alias, d_inode of aliases
44 44 * dcache_hash_bucket lock protects:
45 45 * - the dcache hash table
46 46 * s_anon bl list spinlock protects:
... ... @@ -58,7 +58,7 @@
58 58 * - d_alias, d_inode
59 59 *
60 60 * Ordering:
61   - * dcache_inode_lock
  61 + * dentry->d_inode->i_lock
62 62 * dentry->d_lock
63 63 * dcache_lru_lock
64 64 * dcache_hash_bucket lock
65 65  
... ... @@ -78,12 +78,10 @@
78 78 int sysctl_vfs_cache_pressure __read_mostly = 100;
79 79 EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
80 80  
81   -__cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_inode_lock);
82 81 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lru_lock);
83 82 __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
84 83  
85 84 EXPORT_SYMBOL(rename_lock);
86   -EXPORT_SYMBOL(dcache_inode_lock);
87 85  
88 86 static struct kmem_cache *dentry_cache __read_mostly;
89 87  
90 88  
... ... @@ -196,14 +194,14 @@
196 194 */
197 195 static void dentry_iput(struct dentry * dentry)
198 196 __releases(dentry->d_lock)
199   - __releases(dcache_inode_lock)
  197 + __releases(dentry->d_inode->i_lock)
200 198 {
201 199 struct inode *inode = dentry->d_inode;
202 200 if (inode) {
203 201 dentry->d_inode = NULL;
204 202 list_del_init(&dentry->d_alias);
205 203 spin_unlock(&dentry->d_lock);
206   - spin_unlock(&dcache_inode_lock);
  204 + spin_unlock(&inode->i_lock);
207 205 if (!inode->i_nlink)
208 206 fsnotify_inoderemove(inode);
209 207 if (dentry->d_op && dentry->d_op->d_iput)
... ... @@ -212,7 +210,6 @@
212 210 iput(inode);
213 211 } else {
214 212 spin_unlock(&dentry->d_lock);
215   - spin_unlock(&dcache_inode_lock);
216 213 }
217 214 }
218 215  
219 216  
... ... @@ -222,14 +219,14 @@
222 219 */
223 220 static void dentry_unlink_inode(struct dentry * dentry)
224 221 __releases(dentry->d_lock)
225   - __releases(dcache_inode_lock)
  222 + __releases(dentry->d_inode->i_lock)
226 223 {
227 224 struct inode *inode = dentry->d_inode;
228 225 dentry->d_inode = NULL;
229 226 list_del_init(&dentry->d_alias);
230 227 dentry_rcuwalk_barrier(dentry);
231 228 spin_unlock(&dentry->d_lock);
232   - spin_unlock(&dcache_inode_lock);
  229 + spin_unlock(&inode->i_lock);
233 230 if (!inode->i_nlink)
234 231 fsnotify_inoderemove(inode);
235 232 if (dentry->d_op && dentry->d_op->d_iput)
... ... @@ -295,7 +292,7 @@
295 292 static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
296 293 __releases(dentry->d_lock)
297 294 __releases(parent->d_lock)
298   - __releases(dcache_inode_lock)
  295 + __releases(dentry->d_inode->i_lock)
299 296 {
300 297 dentry->d_parent = NULL;
301 298 list_del(&dentry->d_u.d_child);
302 299  
... ... @@ -370,9 +367,11 @@
370 367 static inline struct dentry *dentry_kill(struct dentry *dentry, int ref)
371 368 __releases(dentry->d_lock)
372 369 {
  370 + struct inode *inode;
373 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)) {
376 375 relock:
377 376 spin_unlock(&dentry->d_lock);
378 377 cpu_relax();
... ... @@ -383,7 +382,8 @@
383 382 else
384 383 parent = dentry->d_parent;
385 384 if (parent && !spin_trylock(&parent->d_lock)) {
386   - spin_unlock(&dcache_inode_lock);
  385 + if (inode)
  386 + spin_unlock(&inode->i_lock);
387 387 goto relock;
388 388 }
389 389  
390 390  
... ... @@ -618,9 +618,9 @@
618 618 struct dentry *de = NULL;
619 619  
620 620 if (!list_empty(&inode->i_dentry)) {
621   - spin_lock(&dcache_inode_lock);
  621 + spin_lock(&inode->i_lock);
622 622 de = __d_find_alias(inode, 0);
623   - spin_unlock(&dcache_inode_lock);
  623 + spin_unlock(&inode->i_lock);
624 624 }
625 625 return de;
626 626 }
627 627  
628 628  
... ... @@ -634,20 +634,20 @@
634 634 {
635 635 struct dentry *dentry;
636 636 restart:
637   - spin_lock(&dcache_inode_lock);
  637 + spin_lock(&inode->i_lock);
638 638 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
639 639 spin_lock(&dentry->d_lock);
640 640 if (!dentry->d_count) {
641 641 __dget_dlock(dentry);
642 642 __d_drop(dentry);
643 643 spin_unlock(&dentry->d_lock);
644   - spin_unlock(&dcache_inode_lock);
  644 + spin_unlock(&inode->i_lock);
645 645 dput(dentry);
646 646 goto restart;
647 647 }
648 648 spin_unlock(&dentry->d_lock);
649 649 }
650   - spin_unlock(&dcache_inode_lock);
  650 + spin_unlock(&inode->i_lock);
651 651 }
652 652 EXPORT_SYMBOL(d_prune_aliases);
653 653  
654 654  
... ... @@ -1392,9 +1392,11 @@
1392 1392 void d_instantiate(struct dentry *entry, struct inode * inode)
1393 1393 {
1394 1394 BUG_ON(!list_empty(&entry->d_alias));
1395   - spin_lock(&dcache_inode_lock);
  1395 + if (inode)
  1396 + spin_lock(&inode->i_lock);
1396 1397 __d_instantiate(entry, inode);
1397   - spin_unlock(&dcache_inode_lock);
  1398 + if (inode)
  1399 + spin_unlock(&inode->i_lock);
1398 1400 security_d_instantiate(entry, inode);
1399 1401 }
1400 1402 EXPORT_SYMBOL(d_instantiate);
1401 1403  
... ... @@ -1458,9 +1460,11 @@
1458 1460  
1459 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 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 1469 if (!result) {
1466 1470 security_d_instantiate(entry, inode);
1467 1471  
... ... @@ -1542,10 +1546,10 @@
1542 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 1550 res = __d_find_alias(inode, 0);
1547 1551 if (res) {
1548   - spin_unlock(&dcache_inode_lock);
  1552 + spin_unlock(&inode->i_lock);
1549 1553 dput(tmp);
1550 1554 goto out_iput;
1551 1555 }
... ... @@ -1561,7 +1565,7 @@
1561 1565 hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon);
1562 1566 __bit_spin_unlock(0, (unsigned long *)&tmp->d_sb->s_anon.first);
1563 1567 spin_unlock(&tmp->d_lock);
1564   - spin_unlock(&dcache_inode_lock);
  1568 + spin_unlock(&inode->i_lock);
1565 1569  
1566 1570 return tmp;
1567 1571  
1568 1572  
1569 1573  
1570 1574  
... ... @@ -1592,18 +1596,18 @@
1592 1596 struct dentry *new = NULL;
1593 1597  
1594 1598 if (inode && S_ISDIR(inode->i_mode)) {
1595   - spin_lock(&dcache_inode_lock);
  1599 + spin_lock(&inode->i_lock);
1596 1600 new = __d_find_alias(inode, 1);
1597 1601 if (new) {
1598 1602 BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
1599   - spin_unlock(&dcache_inode_lock);
  1603 + spin_unlock(&inode->i_lock);
1600 1604 security_d_instantiate(new, inode);
1601 1605 d_move(new, dentry);
1602 1606 iput(inode);
1603 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 1609 __d_instantiate(dentry, inode);
1606   - spin_unlock(&dcache_inode_lock);
  1610 + spin_unlock(&inode->i_lock);
1607 1611 security_d_instantiate(dentry, inode);
1608 1612 d_rehash(dentry);
1609 1613 }
1610 1614  
... ... @@ -1676,10 +1680,10 @@
1676 1680 * Negative dentry: instantiate it unless the inode is a directory and
1677 1681 * already has a dentry.
1678 1682 */
1679   - spin_lock(&dcache_inode_lock);
  1683 + spin_lock(&inode->i_lock);
1680 1684 if (!S_ISDIR(inode->i_mode) || list_empty(&inode->i_dentry)) {
1681 1685 __d_instantiate(found, inode);
1682   - spin_unlock(&dcache_inode_lock);
  1686 + spin_unlock(&inode->i_lock);
1683 1687 security_d_instantiate(found, inode);
1684 1688 return found;
1685 1689 }
... ... @@ -1690,7 +1694,7 @@
1690 1694 */
1691 1695 new = list_entry(inode->i_dentry.next, struct dentry, d_alias);
1692 1696 __dget(new);
1693   - spin_unlock(&dcache_inode_lock);
  1697 + spin_unlock(&inode->i_lock);
1694 1698 security_d_instantiate(found, inode);
1695 1699 d_move(new, found);
1696 1700 iput(inode);
1697 1701  
1698 1702  
... ... @@ -2004,15 +2008,17 @@
2004 2008  
2005 2009 void d_delete(struct dentry * dentry)
2006 2010 {
  2011 + struct inode *inode;
2007 2012 int isdir = 0;
2008 2013 /*
2009 2014 * Are we the only user?
2010 2015 */
2011 2016 again:
2012 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 2020 if (dentry->d_count == 1) {
2015   - if (!spin_trylock(&dcache_inode_lock)) {
  2021 + if (inode && !spin_trylock(&inode->i_lock)) {
2016 2022 spin_unlock(&dentry->d_lock);
2017 2023 cpu_relax();
2018 2024 goto again;
2019 2025  
... ... @@ -2266,13 +2272,13 @@
2266 2272 * This helper attempts to cope with remotely renamed directories
2267 2273 *
2268 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 2277 * Note: If ever the locking in lock_rename() changes, then please
2272 2278 * remember to update this too...
2273 2279 */
2274   -static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
2275   - __releases(dcache_inode_lock)
  2280 +static struct dentry *__d_unalias(struct inode *inode,
  2281 + struct dentry *dentry, struct dentry *alias)
2276 2282 {
2277 2283 struct mutex *m1 = NULL, *m2 = NULL;
2278 2284 struct dentry *ret;
... ... @@ -2298,7 +2304,7 @@
2298 2304 d_move(alias, dentry);
2299 2305 ret = alias;
2300 2306 out_err:
2301   - spin_unlock(&dcache_inode_lock);
  2307 + spin_unlock(&inode->i_lock);
2302 2308 if (m2)
2303 2309 mutex_unlock(m2);
2304 2310 if (m1)
... ... @@ -2371,7 +2377,7 @@
2371 2377 goto out_nolock;
2372 2378 }
2373 2379  
2374   - spin_lock(&dcache_inode_lock);
  2380 + spin_lock(&inode->i_lock);
2375 2381  
2376 2382 if (S_ISDIR(inode->i_mode)) {
2377 2383 struct dentry *alias;
... ... @@ -2388,7 +2394,7 @@
2388 2394 goto found;
2389 2395 }
2390 2396 /* Nope, but we must(!) avoid directory aliasing */
2391   - actual = __d_unalias(dentry, alias);
  2397 + actual = __d_unalias(inode, dentry, alias);
2392 2398 if (IS_ERR(actual))
2393 2399 dput(alias);
2394 2400 goto out_nolock;
... ... @@ -2406,7 +2412,7 @@
2406 2412 found:
2407 2413 _d_rehash(actual);
2408 2414 spin_unlock(&actual->d_lock);
2409   - spin_unlock(&dcache_inode_lock);
  2415 + spin_unlock(&inode->i_lock);
2410 2416 out_nolock:
2411 2417 if (actual == dentry) {
2412 2418 security_d_instantiate(dentry, inode);
... ... @@ -43,24 +43,26 @@
43 43 void *context)
44 44 {
45 45 struct dentry *dentry, *toput = NULL;
  46 + struct inode *inode;
46 47  
47 48 if (acceptable(context, result))
48 49 return result;
49 50  
50   - spin_lock(&dcache_inode_lock);
51   - list_for_each_entry(dentry, &result->d_inode->i_dentry, d_alias) {
  51 + inode = result->d_inode;
  52 + spin_lock(&inode->i_lock);
  53 + list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
52 54 dget(dentry);
53   - spin_unlock(&dcache_inode_lock);
  55 + spin_unlock(&inode->i_lock);
54 56 if (toput)
55 57 dput(toput);
56 58 if (dentry != result && acceptable(context, dentry)) {
57 59 dput(result);
58 60 return dentry;
59 61 }
60   - spin_lock(&dcache_inode_lock);
  62 + spin_lock(&inode->i_lock);
61 63 toput = dentry;
62 64 }
63   - spin_unlock(&dcache_inode_lock);
  65 + spin_unlock(&inode->i_lock);
64 66  
65 67 if (toput)
66 68 dput(toput);
... ... @@ -63,11 +63,11 @@
63 63 * This again causes shrink_dcache_for_umount_subtree() to
64 64 * Oops, since the test for IS_ROOT() will fail.
65 65 */
66   - spin_lock(&dcache_inode_lock);
  66 + spin_lock(&sb->s_root->d_inode->i_lock);
67 67 spin_lock(&sb->s_root->d_lock);
68 68 list_del_init(&sb->s_root->d_alias);
69 69 spin_unlock(&sb->s_root->d_lock);
70   - spin_unlock(&dcache_inode_lock);
  70 + spin_unlock(&sb->s_root->d_inode->i_lock);
71 71 }
72 72 return 0;
73 73 }
fs/notify/fsnotify.c
... ... @@ -59,7 +59,7 @@
59 59 /* determine if the children should tell inode about their events */
60 60 watched = fsnotify_inode_watches_children(inode);
61 61  
62   - spin_lock(&dcache_inode_lock);
  62 + spin_lock(&inode->i_lock);
63 63 /* run all of the dentries associated with this inode. Since this is a
64 64 * directory, there damn well better only be one item on this list */
65 65 list_for_each_entry(alias, &inode->i_dentry, d_alias) {
... ... @@ -82,7 +82,7 @@
82 82 }
83 83 spin_unlock(&alias->d_lock);
84 84 }
85   - spin_unlock(&dcache_inode_lock);
  85 + spin_unlock(&inode->i_lock);
86 86 }
87 87  
88 88 /* Notify this dentry's parent about a child's events. */
... ... @@ -175,7 +175,7 @@
175 175 struct list_head *p;
176 176 struct dentry *dentry = NULL;
177 177  
178   - spin_lock(&dcache_inode_lock);
  178 + spin_lock(&inode->i_lock);
179 179 list_for_each(p, &inode->i_dentry) {
180 180 dentry = list_entry(p, struct dentry, d_alias);
181 181  
... ... @@ -193,7 +193,7 @@
193 193 dentry = NULL;
194 194 }
195 195  
196   - spin_unlock(&dcache_inode_lock);
  196 + spin_unlock(&inode->i_lock);
197 197  
198 198 return dentry;
199 199 }
include/linux/dcache.h
... ... @@ -191,7 +191,6 @@
191 191 #define DCACHE_OP_REVALIDATE 0x4000
192 192 #define DCACHE_OP_DELETE 0x8000
193 193  
194   -extern spinlock_t dcache_inode_lock;
195 194 extern seqlock_t rename_lock;
196 195  
197 196 static inline int dname_external(struct dentry *dentry)