aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-10-26 19:19:16 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-11-03 15:20:29 -0500
commit946e51f2bf37f1656916eb75bd0742ba33983c28 (patch)
treee3d2672edeec1117ceda1e8e195eaa8d1c0f5135 /fs/dcache.c
parenta7400222e3eb7d5ce3820d2234905bbeafabd171 (diff)
move d_rcu from overlapping d_child to overlapping d_alias
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c53
1 files changed, 26 insertions, 27 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 3ffef7f4e5cd..8b4c45e40834 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -44,7 +44,7 @@
44/* 44/*
45 * Usage: 45 * Usage:
46 * dcache->d_inode->i_lock protects: 46 * dcache->d_inode->i_lock protects:
47 * - i_dentry, d_alias, d_inode of aliases 47 * - i_dentry, d_u.d_alias, d_inode of aliases
48 * dcache_hash_bucket lock protects: 48 * dcache_hash_bucket lock protects:
49 * - the dcache hash table 49 * - the dcache hash table
50 * s_anon bl list spinlock protects: 50 * s_anon bl list spinlock protects:
@@ -59,7 +59,7 @@
59 * - d_unhashed() 59 * - d_unhashed()
60 * - d_parent and d_subdirs 60 * - d_parent and d_subdirs
61 * - childrens' d_child and d_parent 61 * - childrens' d_child and d_parent
62 * - d_alias, d_inode 62 * - d_u.d_alias, d_inode
63 * 63 *
64 * Ordering: 64 * Ordering:
65 * dentry->d_inode->i_lock 65 * dentry->d_inode->i_lock
@@ -252,14 +252,12 @@ static void __d_free(struct rcu_head *head)
252{ 252{
253 struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); 253 struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu);
254 254
255 WARN_ON(!hlist_unhashed(&dentry->d_alias));
256 kmem_cache_free(dentry_cache, dentry); 255 kmem_cache_free(dentry_cache, dentry);
257} 256}
258 257
259static void __d_free_external(struct rcu_head *head) 258static void __d_free_external(struct rcu_head *head)
260{ 259{
261 struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); 260 struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu);
262 WARN_ON(!hlist_unhashed(&dentry->d_alias));
263 kfree(external_name(dentry)); 261 kfree(external_name(dentry));
264 kmem_cache_free(dentry_cache, dentry); 262 kmem_cache_free(dentry_cache, dentry);
265} 263}
@@ -271,6 +269,7 @@ static inline int dname_external(const struct dentry *dentry)
271 269
272static void dentry_free(struct dentry *dentry) 270static void dentry_free(struct dentry *dentry)
273{ 271{
272 WARN_ON(!hlist_unhashed(&dentry->d_u.d_alias));
274 if (unlikely(dname_external(dentry))) { 273 if (unlikely(dname_external(dentry))) {
275 struct external_name *p = external_name(dentry); 274 struct external_name *p = external_name(dentry);
276 if (likely(atomic_dec_and_test(&p->u.count))) { 275 if (likely(atomic_dec_and_test(&p->u.count))) {
@@ -311,7 +310,7 @@ static void dentry_iput(struct dentry * dentry)
311 struct inode *inode = dentry->d_inode; 310 struct inode *inode = dentry->d_inode;
312 if (inode) { 311 if (inode) {
313 dentry->d_inode = NULL; 312 dentry->d_inode = NULL;
314 hlist_del_init(&dentry->d_alias); 313 hlist_del_init(&dentry->d_u.d_alias);
315 spin_unlock(&dentry->d_lock); 314 spin_unlock(&dentry->d_lock);
316 spin_unlock(&inode->i_lock); 315 spin_unlock(&inode->i_lock);
317 if (!inode->i_nlink) 316 if (!inode->i_nlink)
@@ -336,7 +335,7 @@ static void dentry_unlink_inode(struct dentry * dentry)
336 struct inode *inode = dentry->d_inode; 335 struct inode *inode = dentry->d_inode;
337 __d_clear_type(dentry); 336 __d_clear_type(dentry);
338 dentry->d_inode = NULL; 337 dentry->d_inode = NULL;
339 hlist_del_init(&dentry->d_alias); 338 hlist_del_init(&dentry->d_u.d_alias);
340 dentry_rcuwalk_barrier(dentry); 339 dentry_rcuwalk_barrier(dentry);
341 spin_unlock(&dentry->d_lock); 340 spin_unlock(&dentry->d_lock);
342 spin_unlock(&inode->i_lock); 341 spin_unlock(&inode->i_lock);
@@ -496,7 +495,7 @@ static void __dentry_kill(struct dentry *dentry)
496 } 495 }
497 /* if it was on the hash then remove it */ 496 /* if it was on the hash then remove it */
498 __d_drop(dentry); 497 __d_drop(dentry);
499 list_del(&dentry->d_u.d_child); 498 list_del(&dentry->d_child);
500 /* 499 /*
501 * Inform d_walk() that we are no longer attached to the 500 * Inform d_walk() that we are no longer attached to the
502 * dentry tree 501 * dentry tree
@@ -722,7 +721,7 @@ static struct dentry *__d_find_alias(struct inode *inode)
722 721
723again: 722again:
724 discon_alias = NULL; 723 discon_alias = NULL;
725 hlist_for_each_entry(alias, &inode->i_dentry, d_alias) { 724 hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
726 spin_lock(&alias->d_lock); 725 spin_lock(&alias->d_lock);
727 if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) { 726 if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
728 if (IS_ROOT(alias) && 727 if (IS_ROOT(alias) &&
@@ -772,7 +771,7 @@ void d_prune_aliases(struct inode *inode)
772 struct dentry *dentry; 771 struct dentry *dentry;
773restart: 772restart:
774 spin_lock(&inode->i_lock); 773 spin_lock(&inode->i_lock);
775 hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { 774 hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
776 spin_lock(&dentry->d_lock); 775 spin_lock(&dentry->d_lock);
777 if (!dentry->d_lockref.count) { 776 if (!dentry->d_lockref.count) {
778 struct dentry *parent = lock_parent(dentry); 777 struct dentry *parent = lock_parent(dentry);
@@ -1050,7 +1049,7 @@ repeat:
1050resume: 1049resume:
1051 while (next != &this_parent->d_subdirs) { 1050 while (next != &this_parent->d_subdirs) {
1052 struct list_head *tmp = next; 1051 struct list_head *tmp = next;
1053 struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child); 1052 struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
1054 next = tmp->next; 1053 next = tmp->next;
1055 1054
1056 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); 1055 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
@@ -1102,7 +1101,7 @@ resume:
1102 goto rename_retry; 1101 goto rename_retry;
1103 } 1102 }
1104 rcu_read_unlock(); 1103 rcu_read_unlock();
1105 next = child->d_u.d_child.next; 1104 next = child->d_child.next;
1106 goto resume; 1105 goto resume;
1107 } 1106 }
1108 if (need_seqretry(&rename_lock, seq)) { 1107 if (need_seqretry(&rename_lock, seq)) {
@@ -1454,8 +1453,8 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
1454 INIT_HLIST_BL_NODE(&dentry->d_hash); 1453 INIT_HLIST_BL_NODE(&dentry->d_hash);
1455 INIT_LIST_HEAD(&dentry->d_lru); 1454 INIT_LIST_HEAD(&dentry->d_lru);
1456 INIT_LIST_HEAD(&dentry->d_subdirs); 1455 INIT_LIST_HEAD(&dentry->d_subdirs);
1457 INIT_HLIST_NODE(&dentry->d_alias); 1456 INIT_HLIST_NODE(&dentry->d_u.d_alias);
1458 INIT_LIST_HEAD(&dentry->d_u.d_child); 1457 INIT_LIST_HEAD(&dentry->d_child);
1459 d_set_d_op(dentry, dentry->d_sb->s_d_op); 1458 d_set_d_op(dentry, dentry->d_sb->s_d_op);
1460 1459
1461 this_cpu_inc(nr_dentry); 1460 this_cpu_inc(nr_dentry);
@@ -1485,7 +1484,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
1485 */ 1484 */
1486 __dget_dlock(parent); 1485 __dget_dlock(parent);
1487 dentry->d_parent = parent; 1486 dentry->d_parent = parent;
1488 list_add(&dentry->d_u.d_child, &parent->d_subdirs); 1487 list_add(&dentry->d_child, &parent->d_subdirs);
1489 spin_unlock(&parent->d_lock); 1488 spin_unlock(&parent->d_lock);
1490 1489
1491 return dentry; 1490 return dentry;
@@ -1578,7 +1577,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
1578 spin_lock(&dentry->d_lock); 1577 spin_lock(&dentry->d_lock);
1579 __d_set_type(dentry, add_flags); 1578 __d_set_type(dentry, add_flags);
1580 if (inode) 1579 if (inode)
1581 hlist_add_head(&dentry->d_alias, &inode->i_dentry); 1580 hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
1582 dentry->d_inode = inode; 1581 dentry->d_inode = inode;
1583 dentry_rcuwalk_barrier(dentry); 1582 dentry_rcuwalk_barrier(dentry);
1584 spin_unlock(&dentry->d_lock); 1583 spin_unlock(&dentry->d_lock);
@@ -1602,7 +1601,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
1602 1601
1603void d_instantiate(struct dentry *entry, struct inode * inode) 1602void d_instantiate(struct dentry *entry, struct inode * inode)
1604{ 1603{
1605 BUG_ON(!hlist_unhashed(&entry->d_alias)); 1604 BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
1606 if (inode) 1605 if (inode)
1607 spin_lock(&inode->i_lock); 1606 spin_lock(&inode->i_lock);
1608 __d_instantiate(entry, inode); 1607 __d_instantiate(entry, inode);
@@ -1641,7 +1640,7 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry,
1641 return NULL; 1640 return NULL;
1642 } 1641 }
1643 1642
1644 hlist_for_each_entry(alias, &inode->i_dentry, d_alias) { 1643 hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
1645 /* 1644 /*
1646 * Don't need alias->d_lock here, because aliases with 1645 * Don't need alias->d_lock here, because aliases with
1647 * d_parent == entry->d_parent are not subject to name or 1646 * d_parent == entry->d_parent are not subject to name or
@@ -1667,7 +1666,7 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
1667{ 1666{
1668 struct dentry *result; 1667 struct dentry *result;
1669 1668
1670 BUG_ON(!hlist_unhashed(&entry->d_alias)); 1669 BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
1671 1670
1672 if (inode) 1671 if (inode)
1673 spin_lock(&inode->i_lock); 1672 spin_lock(&inode->i_lock);
@@ -1698,7 +1697,7 @@ EXPORT_SYMBOL(d_instantiate_unique);
1698 */ 1697 */
1699int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode) 1698int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode)
1700{ 1699{
1701 BUG_ON(!hlist_unhashed(&entry->d_alias)); 1700 BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
1702 1701
1703 spin_lock(&inode->i_lock); 1702 spin_lock(&inode->i_lock);
1704 if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) { 1703 if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) {
@@ -1737,7 +1736,7 @@ static struct dentry * __d_find_any_alias(struct inode *inode)
1737 1736
1738 if (hlist_empty(&inode->i_dentry)) 1737 if (hlist_empty(&inode->i_dentry))
1739 return NULL; 1738 return NULL;
1740 alias = hlist_entry(inode->i_dentry.first, struct dentry, d_alias); 1739 alias = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias);
1741 __dget(alias); 1740 __dget(alias);
1742 return alias; 1741 return alias;
1743} 1742}
@@ -1799,7 +1798,7 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected)
1799 spin_lock(&tmp->d_lock); 1798 spin_lock(&tmp->d_lock);
1800 tmp->d_inode = inode; 1799 tmp->d_inode = inode;
1801 tmp->d_flags |= add_flags; 1800 tmp->d_flags |= add_flags;
1802 hlist_add_head(&tmp->d_alias, &inode->i_dentry); 1801 hlist_add_head(&tmp->d_u.d_alias, &inode->i_dentry);
1803 hlist_bl_lock(&tmp->d_sb->s_anon); 1802 hlist_bl_lock(&tmp->d_sb->s_anon);
1804 hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); 1803 hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon);
1805 hlist_bl_unlock(&tmp->d_sb->s_anon); 1804 hlist_bl_unlock(&tmp->d_sb->s_anon);
@@ -2234,7 +2233,7 @@ int d_validate(struct dentry *dentry, struct dentry *dparent)
2234 struct dentry *child; 2233 struct dentry *child;
2235 2234
2236 spin_lock(&dparent->d_lock); 2235 spin_lock(&dparent->d_lock);
2237 list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) { 2236 list_for_each_entry(child, &dparent->d_subdirs, d_child) {
2238 if (dentry == child) { 2237 if (dentry == child) {
2239 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); 2238 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
2240 __dget_dlock(dentry); 2239 __dget_dlock(dentry);
@@ -2525,13 +2524,13 @@ static void __d_move(struct dentry *dentry, struct dentry *target,
2525 /* splicing a tree */ 2524 /* splicing a tree */
2526 dentry->d_parent = target->d_parent; 2525 dentry->d_parent = target->d_parent;
2527 target->d_parent = target; 2526 target->d_parent = target;
2528 list_del_init(&target->d_u.d_child); 2527 list_del_init(&target->d_child);
2529 list_move(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs); 2528 list_move(&dentry->d_child, &dentry->d_parent->d_subdirs);
2530 } else { 2529 } else {
2531 /* swapping two dentries */ 2530 /* swapping two dentries */
2532 swap(dentry->d_parent, target->d_parent); 2531 swap(dentry->d_parent, target->d_parent);
2533 list_move(&target->d_u.d_child, &target->d_parent->d_subdirs); 2532 list_move(&target->d_child, &target->d_parent->d_subdirs);
2534 list_move(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs); 2533 list_move(&dentry->d_child, &dentry->d_parent->d_subdirs);
2535 if (exchange) 2534 if (exchange)
2536 fsnotify_d_move(target); 2535 fsnotify_d_move(target);
2537 fsnotify_d_move(dentry); 2536 fsnotify_d_move(dentry);
@@ -3320,7 +3319,7 @@ void d_tmpfile(struct dentry *dentry, struct inode *inode)
3320{ 3319{
3321 inode_dec_link_count(inode); 3320 inode_dec_link_count(inode);
3322 BUG_ON(dentry->d_name.name != dentry->d_iname || 3321 BUG_ON(dentry->d_name.name != dentry->d_iname ||
3323 !hlist_unhashed(&dentry->d_alias) || 3322 !hlist_unhashed(&dentry->d_u.d_alias) ||
3324 !d_unlinked(dentry)); 3323 !d_unlinked(dentry));
3325 spin_lock(&dentry->d_parent->d_lock); 3324 spin_lock(&dentry->d_parent->d_lock);
3326 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); 3325 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);