diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 226 |
1 files changed, 112 insertions, 114 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 2a6bd9a4ae97..37f72ee5bf7c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/hardirq.h> | 35 | #include <linux/hardirq.h> |
36 | #include <linux/bit_spinlock.h> | 36 | #include <linux/bit_spinlock.h> |
37 | #include <linux/rculist_bl.h> | 37 | #include <linux/rculist_bl.h> |
38 | #include <linux/prefetch.h> | ||
38 | #include "internal.h" | 39 | #include "internal.h" |
39 | 40 | ||
40 | /* | 41 | /* |
@@ -99,12 +100,9 @@ static struct kmem_cache *dentry_cache __read_mostly; | |||
99 | static unsigned int d_hash_mask __read_mostly; | 100 | static unsigned int d_hash_mask __read_mostly; |
100 | static unsigned int d_hash_shift __read_mostly; | 101 | static unsigned int d_hash_shift __read_mostly; |
101 | 102 | ||
102 | struct dcache_hash_bucket { | 103 | static struct hlist_bl_head *dentry_hashtable __read_mostly; |
103 | struct hlist_bl_head head; | ||
104 | }; | ||
105 | static struct dcache_hash_bucket *dentry_hashtable __read_mostly; | ||
106 | 104 | ||
107 | static inline struct dcache_hash_bucket *d_hash(struct dentry *parent, | 105 | static inline struct hlist_bl_head *d_hash(struct dentry *parent, |
108 | unsigned long hash) | 106 | unsigned long hash) |
109 | { | 107 | { |
110 | hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES; | 108 | hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES; |
@@ -112,16 +110,6 @@ static inline struct dcache_hash_bucket *d_hash(struct dentry *parent, | |||
112 | return dentry_hashtable + (hash & D_HASHMASK); | 110 | return dentry_hashtable + (hash & D_HASHMASK); |
113 | } | 111 | } |
114 | 112 | ||
115 | static inline void spin_lock_bucket(struct dcache_hash_bucket *b) | ||
116 | { | ||
117 | bit_spin_lock(0, (unsigned long *)&b->head.first); | ||
118 | } | ||
119 | |||
120 | static inline void spin_unlock_bucket(struct dcache_hash_bucket *b) | ||
121 | { | ||
122 | __bit_spin_unlock(0, (unsigned long *)&b->head.first); | ||
123 | } | ||
124 | |||
125 | /* Statistics gathering. */ | 113 | /* Statistics gathering. */ |
126 | struct dentry_stat_t dentry_stat = { | 114 | struct dentry_stat_t dentry_stat = { |
127 | .age_limit = 45, | 115 | .age_limit = 45, |
@@ -167,8 +155,8 @@ static void d_free(struct dentry *dentry) | |||
167 | if (dentry->d_op && dentry->d_op->d_release) | 155 | if (dentry->d_op && dentry->d_op->d_release) |
168 | dentry->d_op->d_release(dentry); | 156 | dentry->d_op->d_release(dentry); |
169 | 157 | ||
170 | /* if dentry was never inserted into hash, immediate free is OK */ | 158 | /* if dentry was never visible to RCU, immediate free is OK */ |
171 | if (hlist_bl_unhashed(&dentry->d_hash)) | 159 | if (!(dentry->d_flags & DCACHE_RCUACCESS)) |
172 | __d_free(&dentry->d_u.d_rcu); | 160 | __d_free(&dentry->d_u.d_rcu); |
173 | else | 161 | else |
174 | call_rcu(&dentry->d_u.d_rcu, __d_free); | 162 | call_rcu(&dentry->d_u.d_rcu, __d_free); |
@@ -296,8 +284,12 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) | |||
296 | __releases(parent->d_lock) | 284 | __releases(parent->d_lock) |
297 | __releases(dentry->d_inode->i_lock) | 285 | __releases(dentry->d_inode->i_lock) |
298 | { | 286 | { |
299 | dentry->d_parent = NULL; | ||
300 | list_del(&dentry->d_u.d_child); | 287 | list_del(&dentry->d_u.d_child); |
288 | /* | ||
289 | * Inform try_to_ascend() that we are no longer attached to the | ||
290 | * dentry tree | ||
291 | */ | ||
292 | dentry->d_flags |= DCACHE_DISCONNECTED; | ||
301 | if (parent) | 293 | if (parent) |
302 | spin_unlock(&parent->d_lock); | 294 | spin_unlock(&parent->d_lock); |
303 | dentry_iput(dentry); | 295 | dentry_iput(dentry); |
@@ -326,28 +318,19 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) | |||
326 | */ | 318 | */ |
327 | void __d_drop(struct dentry *dentry) | 319 | void __d_drop(struct dentry *dentry) |
328 | { | 320 | { |
329 | if (!(dentry->d_flags & DCACHE_UNHASHED)) { | 321 | if (!d_unhashed(dentry)) { |
330 | if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) { | 322 | struct hlist_bl_head *b; |
331 | bit_spin_lock(0, | 323 | if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) |
332 | (unsigned long *)&dentry->d_sb->s_anon.first); | 324 | b = &dentry->d_sb->s_anon; |
333 | dentry->d_flags |= DCACHE_UNHASHED; | 325 | else |
334 | hlist_bl_del_init(&dentry->d_hash); | ||
335 | __bit_spin_unlock(0, | ||
336 | (unsigned long *)&dentry->d_sb->s_anon.first); | ||
337 | } else { | ||
338 | struct dcache_hash_bucket *b; | ||
339 | b = d_hash(dentry->d_parent, dentry->d_name.hash); | 326 | b = d_hash(dentry->d_parent, dentry->d_name.hash); |
340 | spin_lock_bucket(b); | 327 | |
341 | /* | 328 | hlist_bl_lock(b); |
342 | * We may not actually need to put DCACHE_UNHASHED | 329 | __hlist_bl_del(&dentry->d_hash); |
343 | * manipulations under the hash lock, but follow | 330 | dentry->d_hash.pprev = NULL; |
344 | * the principle of least surprise. | 331 | hlist_bl_unlock(b); |
345 | */ | 332 | |
346 | dentry->d_flags |= DCACHE_UNHASHED; | 333 | dentry_rcuwalk_barrier(dentry); |
347 | hlist_bl_del_rcu(&dentry->d_hash); | ||
348 | spin_unlock_bucket(b); | ||
349 | dentry_rcuwalk_barrier(dentry); | ||
350 | } | ||
351 | } | 334 | } |
352 | } | 335 | } |
353 | EXPORT_SYMBOL(__d_drop); | 336 | EXPORT_SYMBOL(__d_drop); |
@@ -1012,6 +995,35 @@ void shrink_dcache_for_umount(struct super_block *sb) | |||
1012 | } | 995 | } |
1013 | 996 | ||
1014 | /* | 997 | /* |
998 | * This tries to ascend one level of parenthood, but | ||
999 | * we can race with renaming, so we need to re-check | ||
1000 | * the parenthood after dropping the lock and check | ||
1001 | * that the sequence number still matches. | ||
1002 | */ | ||
1003 | static struct dentry *try_to_ascend(struct dentry *old, int locked, unsigned seq) | ||
1004 | { | ||
1005 | struct dentry *new = old->d_parent; | ||
1006 | |||
1007 | rcu_read_lock(); | ||
1008 | spin_unlock(&old->d_lock); | ||
1009 | spin_lock(&new->d_lock); | ||
1010 | |||
1011 | /* | ||
1012 | * might go back up the wrong parent if we have had a rename | ||
1013 | * or deletion | ||
1014 | */ | ||
1015 | if (new != old->d_parent || | ||
1016 | (old->d_flags & DCACHE_DISCONNECTED) || | ||
1017 | (!locked && read_seqretry(&rename_lock, seq))) { | ||
1018 | spin_unlock(&new->d_lock); | ||
1019 | new = NULL; | ||
1020 | } | ||
1021 | rcu_read_unlock(); | ||
1022 | return new; | ||
1023 | } | ||
1024 | |||
1025 | |||
1026 | /* | ||
1015 | * Search for at least 1 mount point in the dentry's subdirs. | 1027 | * Search for at least 1 mount point in the dentry's subdirs. |
1016 | * We descend to the next level whenever the d_subdirs | 1028 | * We descend to the next level whenever the d_subdirs |
1017 | * list is non-empty and continue searching. | 1029 | * list is non-empty and continue searching. |
@@ -1066,24 +1078,10 @@ resume: | |||
1066 | * All done at this level ... ascend and resume the search. | 1078 | * All done at this level ... ascend and resume the search. |
1067 | */ | 1079 | */ |
1068 | if (this_parent != parent) { | 1080 | if (this_parent != parent) { |
1069 | struct dentry *tmp; | 1081 | struct dentry *child = this_parent; |
1070 | struct dentry *child; | 1082 | this_parent = try_to_ascend(this_parent, locked, seq); |
1071 | 1083 | if (!this_parent) | |
1072 | tmp = this_parent->d_parent; | ||
1073 | rcu_read_lock(); | ||
1074 | spin_unlock(&this_parent->d_lock); | ||
1075 | child = this_parent; | ||
1076 | this_parent = tmp; | ||
1077 | spin_lock(&this_parent->d_lock); | ||
1078 | /* might go back up the wrong parent if we have had a rename | ||
1079 | * or deletion */ | ||
1080 | if (this_parent != child->d_parent || | ||
1081 | (!locked && read_seqretry(&rename_lock, seq))) { | ||
1082 | spin_unlock(&this_parent->d_lock); | ||
1083 | rcu_read_unlock(); | ||
1084 | goto rename_retry; | 1084 | goto rename_retry; |
1085 | } | ||
1086 | rcu_read_unlock(); | ||
1087 | next = child->d_u.d_child.next; | 1085 | next = child->d_u.d_child.next; |
1088 | goto resume; | 1086 | goto resume; |
1089 | } | 1087 | } |
@@ -1181,24 +1179,10 @@ resume: | |||
1181 | * All done at this level ... ascend and resume the search. | 1179 | * All done at this level ... ascend and resume the search. |
1182 | */ | 1180 | */ |
1183 | if (this_parent != parent) { | 1181 | if (this_parent != parent) { |
1184 | struct dentry *tmp; | 1182 | struct dentry *child = this_parent; |
1185 | struct dentry *child; | 1183 | this_parent = try_to_ascend(this_parent, locked, seq); |
1186 | 1184 | if (!this_parent) | |
1187 | tmp = this_parent->d_parent; | ||
1188 | rcu_read_lock(); | ||
1189 | spin_unlock(&this_parent->d_lock); | ||
1190 | child = this_parent; | ||
1191 | this_parent = tmp; | ||
1192 | spin_lock(&this_parent->d_lock); | ||
1193 | /* might go back up the wrong parent if we have had a rename | ||
1194 | * or deletion */ | ||
1195 | if (this_parent != child->d_parent || | ||
1196 | (!locked && read_seqretry(&rename_lock, seq))) { | ||
1197 | spin_unlock(&this_parent->d_lock); | ||
1198 | rcu_read_unlock(); | ||
1199 | goto rename_retry; | 1185 | goto rename_retry; |
1200 | } | ||
1201 | rcu_read_unlock(); | ||
1202 | next = child->d_u.d_child.next; | 1186 | next = child->d_u.d_child.next; |
1203 | goto resume; | 1187 | goto resume; |
1204 | } | 1188 | } |
@@ -1236,7 +1220,7 @@ void shrink_dcache_parent(struct dentry * parent) | |||
1236 | EXPORT_SYMBOL(shrink_dcache_parent); | 1220 | EXPORT_SYMBOL(shrink_dcache_parent); |
1237 | 1221 | ||
1238 | /* | 1222 | /* |
1239 | * Scan `nr' dentries and return the number which remain. | 1223 | * Scan `sc->nr_slab_to_reclaim' dentries and return the number which remain. |
1240 | * | 1224 | * |
1241 | * We need to avoid reentering the filesystem if the caller is performing a | 1225 | * We need to avoid reentering the filesystem if the caller is performing a |
1242 | * GFP_NOFS allocation attempt. One example deadlock is: | 1226 | * GFP_NOFS allocation attempt. One example deadlock is: |
@@ -1247,8 +1231,12 @@ EXPORT_SYMBOL(shrink_dcache_parent); | |||
1247 | * | 1231 | * |
1248 | * In this case we return -1 to tell the caller that we baled. | 1232 | * In this case we return -1 to tell the caller that we baled. |
1249 | */ | 1233 | */ |
1250 | static int shrink_dcache_memory(struct shrinker *shrink, int nr, gfp_t gfp_mask) | 1234 | static int shrink_dcache_memory(struct shrinker *shrink, |
1235 | struct shrink_control *sc) | ||
1251 | { | 1236 | { |
1237 | int nr = sc->nr_to_scan; | ||
1238 | gfp_t gfp_mask = sc->gfp_mask; | ||
1239 | |||
1252 | if (nr) { | 1240 | if (nr) { |
1253 | if (!(gfp_mask & __GFP_FS)) | 1241 | if (!(gfp_mask & __GFP_FS)) |
1254 | return -1; | 1242 | return -1; |
@@ -1299,7 +1287,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) | |||
1299 | dname[name->len] = 0; | 1287 | dname[name->len] = 0; |
1300 | 1288 | ||
1301 | dentry->d_count = 1; | 1289 | dentry->d_count = 1; |
1302 | dentry->d_flags = DCACHE_UNHASHED; | 1290 | dentry->d_flags = 0; |
1303 | spin_lock_init(&dentry->d_lock); | 1291 | spin_lock_init(&dentry->d_lock); |
1304 | seqcount_init(&dentry->d_seq); | 1292 | seqcount_init(&dentry->d_seq); |
1305 | dentry->d_inode = NULL; | 1293 | dentry->d_inode = NULL; |
@@ -1523,6 +1511,28 @@ struct dentry * d_alloc_root(struct inode * root_inode) | |||
1523 | } | 1511 | } |
1524 | EXPORT_SYMBOL(d_alloc_root); | 1512 | EXPORT_SYMBOL(d_alloc_root); |
1525 | 1513 | ||
1514 | static struct dentry * __d_find_any_alias(struct inode *inode) | ||
1515 | { | ||
1516 | struct dentry *alias; | ||
1517 | |||
1518 | if (list_empty(&inode->i_dentry)) | ||
1519 | return NULL; | ||
1520 | alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias); | ||
1521 | __dget(alias); | ||
1522 | return alias; | ||
1523 | } | ||
1524 | |||
1525 | static struct dentry * d_find_any_alias(struct inode *inode) | ||
1526 | { | ||
1527 | struct dentry *de; | ||
1528 | |||
1529 | spin_lock(&inode->i_lock); | ||
1530 | de = __d_find_any_alias(inode); | ||
1531 | spin_unlock(&inode->i_lock); | ||
1532 | return de; | ||
1533 | } | ||
1534 | |||
1535 | |||
1526 | /** | 1536 | /** |
1527 | * d_obtain_alias - find or allocate a dentry for a given inode | 1537 | * d_obtain_alias - find or allocate a dentry for a given inode |
1528 | * @inode: inode to allocate the dentry for | 1538 | * @inode: inode to allocate the dentry for |
@@ -1552,7 +1562,7 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1552 | if (IS_ERR(inode)) | 1562 | if (IS_ERR(inode)) |
1553 | return ERR_CAST(inode); | 1563 | return ERR_CAST(inode); |
1554 | 1564 | ||
1555 | res = d_find_alias(inode); | 1565 | res = d_find_any_alias(inode); |
1556 | if (res) | 1566 | if (res) |
1557 | goto out_iput; | 1567 | goto out_iput; |
1558 | 1568 | ||
@@ -1565,7 +1575,7 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1565 | 1575 | ||
1566 | 1576 | ||
1567 | spin_lock(&inode->i_lock); | 1577 | spin_lock(&inode->i_lock); |
1568 | res = __d_find_alias(inode, 0); | 1578 | res = __d_find_any_alias(inode); |
1569 | if (res) { | 1579 | if (res) { |
1570 | spin_unlock(&inode->i_lock); | 1580 | spin_unlock(&inode->i_lock); |
1571 | dput(tmp); | 1581 | dput(tmp); |
@@ -1579,16 +1589,18 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1579 | tmp->d_inode = inode; | 1589 | tmp->d_inode = inode; |
1580 | tmp->d_flags |= DCACHE_DISCONNECTED; | 1590 | tmp->d_flags |= DCACHE_DISCONNECTED; |
1581 | list_add(&tmp->d_alias, &inode->i_dentry); | 1591 | list_add(&tmp->d_alias, &inode->i_dentry); |
1582 | bit_spin_lock(0, (unsigned long *)&tmp->d_sb->s_anon.first); | 1592 | hlist_bl_lock(&tmp->d_sb->s_anon); |
1583 | tmp->d_flags &= ~DCACHE_UNHASHED; | ||
1584 | hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); | 1593 | hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); |
1585 | __bit_spin_unlock(0, (unsigned long *)&tmp->d_sb->s_anon.first); | 1594 | hlist_bl_unlock(&tmp->d_sb->s_anon); |
1586 | spin_unlock(&tmp->d_lock); | 1595 | spin_unlock(&tmp->d_lock); |
1587 | spin_unlock(&inode->i_lock); | 1596 | spin_unlock(&inode->i_lock); |
1597 | security_d_instantiate(tmp, inode); | ||
1588 | 1598 | ||
1589 | return tmp; | 1599 | return tmp; |
1590 | 1600 | ||
1591 | out_iput: | 1601 | out_iput: |
1602 | if (res && !IS_ERR(res)) | ||
1603 | security_d_instantiate(res, inode); | ||
1592 | iput(inode); | 1604 | iput(inode); |
1593 | return res; | 1605 | return res; |
1594 | } | 1606 | } |
@@ -1759,7 +1771,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, | |||
1759 | unsigned int len = name->len; | 1771 | unsigned int len = name->len; |
1760 | unsigned int hash = name->hash; | 1772 | unsigned int hash = name->hash; |
1761 | const unsigned char *str = name->name; | 1773 | const unsigned char *str = name->name; |
1762 | struct dcache_hash_bucket *b = d_hash(parent, hash); | 1774 | struct hlist_bl_head *b = d_hash(parent, hash); |
1763 | struct hlist_bl_node *node; | 1775 | struct hlist_bl_node *node; |
1764 | struct dentry *dentry; | 1776 | struct dentry *dentry; |
1765 | 1777 | ||
@@ -1781,9 +1793,9 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, | |||
1781 | * false-negative result. d_lookup() protects against concurrent | 1793 | * false-negative result. d_lookup() protects against concurrent |
1782 | * renames using rename_lock seqlock. | 1794 | * renames using rename_lock seqlock. |
1783 | * | 1795 | * |
1784 | * See Documentation/vfs/dcache-locking.txt for more details. | 1796 | * See Documentation/filesystems/path-lookup.txt for more details. |
1785 | */ | 1797 | */ |
1786 | hlist_bl_for_each_entry_rcu(dentry, node, &b->head, d_hash) { | 1798 | hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) { |
1787 | struct inode *i; | 1799 | struct inode *i; |
1788 | const char *tname; | 1800 | const char *tname; |
1789 | int tlen; | 1801 | int tlen; |
@@ -1878,7 +1890,7 @@ struct dentry *__d_lookup(struct dentry *parent, struct qstr *name) | |||
1878 | unsigned int len = name->len; | 1890 | unsigned int len = name->len; |
1879 | unsigned int hash = name->hash; | 1891 | unsigned int hash = name->hash; |
1880 | const unsigned char *str = name->name; | 1892 | const unsigned char *str = name->name; |
1881 | struct dcache_hash_bucket *b = d_hash(parent, hash); | 1893 | struct hlist_bl_head *b = d_hash(parent, hash); |
1882 | struct hlist_bl_node *node; | 1894 | struct hlist_bl_node *node; |
1883 | struct dentry *found = NULL; | 1895 | struct dentry *found = NULL; |
1884 | struct dentry *dentry; | 1896 | struct dentry *dentry; |
@@ -1901,11 +1913,11 @@ struct dentry *__d_lookup(struct dentry *parent, struct qstr *name) | |||
1901 | * false-negative result. d_lookup() protects against concurrent | 1913 | * false-negative result. d_lookup() protects against concurrent |
1902 | * renames using rename_lock seqlock. | 1914 | * renames using rename_lock seqlock. |
1903 | * | 1915 | * |
1904 | * See Documentation/vfs/dcache-locking.txt for more details. | 1916 | * See Documentation/filesystems/path-lookup.txt for more details. |
1905 | */ | 1917 | */ |
1906 | rcu_read_lock(); | 1918 | rcu_read_lock(); |
1907 | 1919 | ||
1908 | hlist_bl_for_each_entry_rcu(dentry, node, &b->head, d_hash) { | 1920 | hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) { |
1909 | const char *tname; | 1921 | const char *tname; |
1910 | int tlen; | 1922 | int tlen; |
1911 | 1923 | ||
@@ -2056,13 +2068,13 @@ again: | |||
2056 | } | 2068 | } |
2057 | EXPORT_SYMBOL(d_delete); | 2069 | EXPORT_SYMBOL(d_delete); |
2058 | 2070 | ||
2059 | static void __d_rehash(struct dentry * entry, struct dcache_hash_bucket *b) | 2071 | static void __d_rehash(struct dentry * entry, struct hlist_bl_head *b) |
2060 | { | 2072 | { |
2061 | BUG_ON(!d_unhashed(entry)); | 2073 | BUG_ON(!d_unhashed(entry)); |
2062 | spin_lock_bucket(b); | 2074 | hlist_bl_lock(b); |
2063 | entry->d_flags &= ~DCACHE_UNHASHED; | 2075 | entry->d_flags |= DCACHE_RCUACCESS; |
2064 | hlist_bl_add_head_rcu(&entry->d_hash, &b->head); | 2076 | hlist_bl_add_head_rcu(&entry->d_hash, b); |
2065 | spin_unlock_bucket(b); | 2077 | hlist_bl_unlock(b); |
2066 | } | 2078 | } |
2067 | 2079 | ||
2068 | static void _d_rehash(struct dentry * entry) | 2080 | static void _d_rehash(struct dentry * entry) |
@@ -2101,7 +2113,7 @@ EXPORT_SYMBOL(d_rehash); | |||
2101 | */ | 2113 | */ |
2102 | void dentry_update_name_case(struct dentry *dentry, struct qstr *name) | 2114 | void dentry_update_name_case(struct dentry *dentry, struct qstr *name) |
2103 | { | 2115 | { |
2104 | BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex)); | 2116 | BUG_ON(!mutex_is_locked(&dentry->d_parent->d_inode->i_mutex)); |
2105 | BUG_ON(dentry->d_name.len != name->len); /* d_lookup gives this */ | 2117 | BUG_ON(dentry->d_name.len != name->len); /* d_lookup gives this */ |
2106 | 2118 | ||
2107 | spin_lock(&dentry->d_lock); | 2119 | spin_lock(&dentry->d_lock); |
@@ -2920,28 +2932,14 @@ resume: | |||
2920 | spin_unlock(&dentry->d_lock); | 2932 | spin_unlock(&dentry->d_lock); |
2921 | } | 2933 | } |
2922 | if (this_parent != root) { | 2934 | if (this_parent != root) { |
2923 | struct dentry *tmp; | 2935 | struct dentry *child = this_parent; |
2924 | struct dentry *child; | ||
2925 | |||
2926 | tmp = this_parent->d_parent; | ||
2927 | if (!(this_parent->d_flags & DCACHE_GENOCIDE)) { | 2936 | if (!(this_parent->d_flags & DCACHE_GENOCIDE)) { |
2928 | this_parent->d_flags |= DCACHE_GENOCIDE; | 2937 | this_parent->d_flags |= DCACHE_GENOCIDE; |
2929 | this_parent->d_count--; | 2938 | this_parent->d_count--; |
2930 | } | 2939 | } |
2931 | rcu_read_lock(); | 2940 | this_parent = try_to_ascend(this_parent, locked, seq); |
2932 | spin_unlock(&this_parent->d_lock); | 2941 | if (!this_parent) |
2933 | child = this_parent; | ||
2934 | this_parent = tmp; | ||
2935 | spin_lock(&this_parent->d_lock); | ||
2936 | /* might go back up the wrong parent if we have had a rename | ||
2937 | * or deletion */ | ||
2938 | if (this_parent != child->d_parent || | ||
2939 | (!locked && read_seqretry(&rename_lock, seq))) { | ||
2940 | spin_unlock(&this_parent->d_lock); | ||
2941 | rcu_read_unlock(); | ||
2942 | goto rename_retry; | 2942 | goto rename_retry; |
2943 | } | ||
2944 | rcu_read_unlock(); | ||
2945 | next = child->d_u.d_child.next; | 2943 | next = child->d_u.d_child.next; |
2946 | goto resume; | 2944 | goto resume; |
2947 | } | 2945 | } |
@@ -3009,7 +3007,7 @@ static void __init dcache_init_early(void) | |||
3009 | 3007 | ||
3010 | dentry_hashtable = | 3008 | dentry_hashtable = |
3011 | alloc_large_system_hash("Dentry cache", | 3009 | alloc_large_system_hash("Dentry cache", |
3012 | sizeof(struct dcache_hash_bucket), | 3010 | sizeof(struct hlist_bl_head), |
3013 | dhash_entries, | 3011 | dhash_entries, |
3014 | 13, | 3012 | 13, |
3015 | HASH_EARLY, | 3013 | HASH_EARLY, |
@@ -3018,7 +3016,7 @@ static void __init dcache_init_early(void) | |||
3018 | 0); | 3016 | 0); |
3019 | 3017 | ||
3020 | for (loop = 0; loop < (1 << d_hash_shift); loop++) | 3018 | for (loop = 0; loop < (1 << d_hash_shift); loop++) |
3021 | INIT_HLIST_BL_HEAD(&dentry_hashtable[loop].head); | 3019 | INIT_HLIST_BL_HEAD(dentry_hashtable + loop); |
3022 | } | 3020 | } |
3023 | 3021 | ||
3024 | static void __init dcache_init(void) | 3022 | static void __init dcache_init(void) |
@@ -3041,7 +3039,7 @@ static void __init dcache_init(void) | |||
3041 | 3039 | ||
3042 | dentry_hashtable = | 3040 | dentry_hashtable = |
3043 | alloc_large_system_hash("Dentry cache", | 3041 | alloc_large_system_hash("Dentry cache", |
3044 | sizeof(struct dcache_hash_bucket), | 3042 | sizeof(struct hlist_bl_head), |
3045 | dhash_entries, | 3043 | dhash_entries, |
3046 | 13, | 3044 | 13, |
3047 | 0, | 3045 | 0, |
@@ -3050,7 +3048,7 @@ static void __init dcache_init(void) | |||
3050 | 0); | 3048 | 0); |
3051 | 3049 | ||
3052 | for (loop = 0; loop < (1 << d_hash_shift); loop++) | 3050 | for (loop = 0; loop < (1 << d_hash_shift); loop++) |
3053 | INIT_HLIST_BL_HEAD(&dentry_hashtable[loop].head); | 3051 | INIT_HLIST_BL_HEAD(dentry_hashtable + loop); |
3054 | } | 3052 | } |
3055 | 3053 | ||
3056 | /* SLAB cache for __getname() consumers */ | 3054 | /* SLAB cache for __getname() consumers */ |