diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 126 |
1 files changed, 47 insertions, 79 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 3ffef7f4e5cd..e605e90d0f0a 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 | ||
259 | static void __d_free_external(struct rcu_head *head) | 258 | static 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 | ||
272 | static void dentry_free(struct dentry *dentry) | 270 | static 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_entry(&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 | ||
723 | again: | 722 | again: |
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; |
773 | restart: | 772 | restart: |
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: | |||
1050 | resume: | 1049 | resume: |
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); |
@@ -1082,33 +1081,31 @@ resume: | |||
1082 | /* | 1081 | /* |
1083 | * All done at this level ... ascend and resume the search. | 1082 | * All done at this level ... ascend and resume the search. |
1084 | */ | 1083 | */ |
1084 | rcu_read_lock(); | ||
1085 | ascend: | ||
1085 | if (this_parent != parent) { | 1086 | if (this_parent != parent) { |
1086 | struct dentry *child = this_parent; | 1087 | struct dentry *child = this_parent; |
1087 | this_parent = child->d_parent; | 1088 | this_parent = child->d_parent; |
1088 | 1089 | ||
1089 | rcu_read_lock(); | ||
1090 | spin_unlock(&child->d_lock); | 1090 | spin_unlock(&child->d_lock); |
1091 | spin_lock(&this_parent->d_lock); | 1091 | spin_lock(&this_parent->d_lock); |
1092 | 1092 | ||
1093 | /* | 1093 | /* might go back up the wrong parent if we have had a rename. */ |
1094 | * might go back up the wrong parent if we have had a rename | 1094 | if (need_seqretry(&rename_lock, seq)) |
1095 | * or deletion | ||
1096 | */ | ||
1097 | if (this_parent != child->d_parent || | ||
1098 | (child->d_flags & DCACHE_DENTRY_KILLED) || | ||
1099 | need_seqretry(&rename_lock, seq)) { | ||
1100 | spin_unlock(&this_parent->d_lock); | ||
1101 | rcu_read_unlock(); | ||
1102 | goto rename_retry; | 1095 | goto rename_retry; |
1096 | next = child->d_child.next; | ||
1097 | while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)) { | ||
1098 | if (next == &this_parent->d_subdirs) | ||
1099 | goto ascend; | ||
1100 | child = list_entry(next, struct dentry, d_child); | ||
1101 | next = next->next; | ||
1103 | } | 1102 | } |
1104 | rcu_read_unlock(); | 1103 | rcu_read_unlock(); |
1105 | next = child->d_u.d_child.next; | ||
1106 | goto resume; | 1104 | goto resume; |
1107 | } | 1105 | } |
1108 | if (need_seqretry(&rename_lock, seq)) { | 1106 | if (need_seqretry(&rename_lock, seq)) |
1109 | spin_unlock(&this_parent->d_lock); | ||
1110 | goto rename_retry; | 1107 | goto rename_retry; |
1111 | } | 1108 | rcu_read_unlock(); |
1112 | if (finish) | 1109 | if (finish) |
1113 | finish(data); | 1110 | finish(data); |
1114 | 1111 | ||
@@ -1118,6 +1115,9 @@ out_unlock: | |||
1118 | return; | 1115 | return; |
1119 | 1116 | ||
1120 | rename_retry: | 1117 | rename_retry: |
1118 | spin_unlock(&this_parent->d_lock); | ||
1119 | rcu_read_unlock(); | ||
1120 | BUG_ON(seq & 1); | ||
1121 | if (!retry) | 1121 | if (!retry) |
1122 | return; | 1122 | return; |
1123 | seq = 1; | 1123 | seq = 1; |
@@ -1454,8 +1454,8 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) | |||
1454 | INIT_HLIST_BL_NODE(&dentry->d_hash); | 1454 | INIT_HLIST_BL_NODE(&dentry->d_hash); |
1455 | INIT_LIST_HEAD(&dentry->d_lru); | 1455 | INIT_LIST_HEAD(&dentry->d_lru); |
1456 | INIT_LIST_HEAD(&dentry->d_subdirs); | 1456 | INIT_LIST_HEAD(&dentry->d_subdirs); |
1457 | INIT_HLIST_NODE(&dentry->d_alias); | 1457 | INIT_HLIST_NODE(&dentry->d_u.d_alias); |
1458 | INIT_LIST_HEAD(&dentry->d_u.d_child); | 1458 | INIT_LIST_HEAD(&dentry->d_child); |
1459 | d_set_d_op(dentry, dentry->d_sb->s_d_op); | 1459 | d_set_d_op(dentry, dentry->d_sb->s_d_op); |
1460 | 1460 | ||
1461 | this_cpu_inc(nr_dentry); | 1461 | this_cpu_inc(nr_dentry); |
@@ -1485,7 +1485,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) | |||
1485 | */ | 1485 | */ |
1486 | __dget_dlock(parent); | 1486 | __dget_dlock(parent); |
1487 | dentry->d_parent = parent; | 1487 | dentry->d_parent = parent; |
1488 | list_add(&dentry->d_u.d_child, &parent->d_subdirs); | 1488 | list_add(&dentry->d_child, &parent->d_subdirs); |
1489 | spin_unlock(&parent->d_lock); | 1489 | spin_unlock(&parent->d_lock); |
1490 | 1490 | ||
1491 | return dentry; | 1491 | return dentry; |
@@ -1578,7 +1578,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode) | |||
1578 | spin_lock(&dentry->d_lock); | 1578 | spin_lock(&dentry->d_lock); |
1579 | __d_set_type(dentry, add_flags); | 1579 | __d_set_type(dentry, add_flags); |
1580 | if (inode) | 1580 | if (inode) |
1581 | hlist_add_head(&dentry->d_alias, &inode->i_dentry); | 1581 | hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry); |
1582 | dentry->d_inode = inode; | 1582 | dentry->d_inode = inode; |
1583 | dentry_rcuwalk_barrier(dentry); | 1583 | dentry_rcuwalk_barrier(dentry); |
1584 | spin_unlock(&dentry->d_lock); | 1584 | spin_unlock(&dentry->d_lock); |
@@ -1602,7 +1602,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode) | |||
1602 | 1602 | ||
1603 | void d_instantiate(struct dentry *entry, struct inode * inode) | 1603 | void d_instantiate(struct dentry *entry, struct inode * inode) |
1604 | { | 1604 | { |
1605 | BUG_ON(!hlist_unhashed(&entry->d_alias)); | 1605 | BUG_ON(!hlist_unhashed(&entry->d_u.d_alias)); |
1606 | if (inode) | 1606 | if (inode) |
1607 | spin_lock(&inode->i_lock); | 1607 | spin_lock(&inode->i_lock); |
1608 | __d_instantiate(entry, inode); | 1608 | __d_instantiate(entry, inode); |
@@ -1641,7 +1641,7 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry, | |||
1641 | return NULL; | 1641 | return NULL; |
1642 | } | 1642 | } |
1643 | 1643 | ||
1644 | hlist_for_each_entry(alias, &inode->i_dentry, d_alias) { | 1644 | hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) { |
1645 | /* | 1645 | /* |
1646 | * Don't need alias->d_lock here, because aliases with | 1646 | * Don't need alias->d_lock here, because aliases with |
1647 | * d_parent == entry->d_parent are not subject to name or | 1647 | * d_parent == entry->d_parent are not subject to name or |
@@ -1667,7 +1667,7 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode) | |||
1667 | { | 1667 | { |
1668 | struct dentry *result; | 1668 | struct dentry *result; |
1669 | 1669 | ||
1670 | BUG_ON(!hlist_unhashed(&entry->d_alias)); | 1670 | BUG_ON(!hlist_unhashed(&entry->d_u.d_alias)); |
1671 | 1671 | ||
1672 | if (inode) | 1672 | if (inode) |
1673 | spin_lock(&inode->i_lock); | 1673 | spin_lock(&inode->i_lock); |
@@ -1698,7 +1698,7 @@ EXPORT_SYMBOL(d_instantiate_unique); | |||
1698 | */ | 1698 | */ |
1699 | int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode) | 1699 | int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode) |
1700 | { | 1700 | { |
1701 | BUG_ON(!hlist_unhashed(&entry->d_alias)); | 1701 | BUG_ON(!hlist_unhashed(&entry->d_u.d_alias)); |
1702 | 1702 | ||
1703 | spin_lock(&inode->i_lock); | 1703 | spin_lock(&inode->i_lock); |
1704 | if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) { | 1704 | if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) { |
@@ -1737,7 +1737,7 @@ static struct dentry * __d_find_any_alias(struct inode *inode) | |||
1737 | 1737 | ||
1738 | if (hlist_empty(&inode->i_dentry)) | 1738 | if (hlist_empty(&inode->i_dentry)) |
1739 | return NULL; | 1739 | return NULL; |
1740 | alias = hlist_entry(inode->i_dentry.first, struct dentry, d_alias); | 1740 | alias = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); |
1741 | __dget(alias); | 1741 | __dget(alias); |
1742 | return alias; | 1742 | return alias; |
1743 | } | 1743 | } |
@@ -1799,7 +1799,7 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected) | |||
1799 | spin_lock(&tmp->d_lock); | 1799 | spin_lock(&tmp->d_lock); |
1800 | tmp->d_inode = inode; | 1800 | tmp->d_inode = inode; |
1801 | tmp->d_flags |= add_flags; | 1801 | tmp->d_flags |= add_flags; |
1802 | hlist_add_head(&tmp->d_alias, &inode->i_dentry); | 1802 | hlist_add_head(&tmp->d_u.d_alias, &inode->i_dentry); |
1803 | hlist_bl_lock(&tmp->d_sb->s_anon); | 1803 | hlist_bl_lock(&tmp->d_sb->s_anon); |
1804 | hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); | 1804 | hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); |
1805 | hlist_bl_unlock(&tmp->d_sb->s_anon); | 1805 | hlist_bl_unlock(&tmp->d_sb->s_anon); |
@@ -1888,51 +1888,19 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, | |||
1888 | * if not go ahead and create it now. | 1888 | * if not go ahead and create it now. |
1889 | */ | 1889 | */ |
1890 | found = d_hash_and_lookup(dentry->d_parent, name); | 1890 | found = d_hash_and_lookup(dentry->d_parent, name); |
1891 | if (unlikely(IS_ERR(found))) | ||
1892 | goto err_out; | ||
1893 | if (!found) { | 1891 | if (!found) { |
1894 | new = d_alloc(dentry->d_parent, name); | 1892 | new = d_alloc(dentry->d_parent, name); |
1895 | if (!new) { | 1893 | if (!new) { |
1896 | found = ERR_PTR(-ENOMEM); | 1894 | found = ERR_PTR(-ENOMEM); |
1897 | goto err_out; | 1895 | } else { |
1898 | } | 1896 | found = d_splice_alias(inode, new); |
1899 | 1897 | if (found) { | |
1900 | found = d_splice_alias(inode, new); | 1898 | dput(new); |
1901 | if (found) { | 1899 | return found; |
1902 | dput(new); | 1900 | } |
1903 | return found; | 1901 | return new; |
1904 | } | ||
1905 | return new; | ||
1906 | } | ||
1907 | |||
1908 | /* | ||
1909 | * If a matching dentry exists, and it's not negative use it. | ||
1910 | * | ||
1911 | * Decrement the reference count to balance the iget() done | ||
1912 | * earlier on. | ||
1913 | */ | ||
1914 | if (found->d_inode) { | ||
1915 | if (unlikely(found->d_inode != inode)) { | ||
1916 | /* This can't happen because bad inodes are unhashed. */ | ||
1917 | BUG_ON(!is_bad_inode(inode)); | ||
1918 | BUG_ON(!is_bad_inode(found->d_inode)); | ||
1919 | } | 1902 | } |
1920 | iput(inode); | ||
1921 | return found; | ||
1922 | } | 1903 | } |
1923 | |||
1924 | /* | ||
1925 | * Negative dentry: instantiate it unless the inode is a directory and | ||
1926 | * already has a dentry. | ||
1927 | */ | ||
1928 | new = d_splice_alias(inode, found); | ||
1929 | if (new) { | ||
1930 | dput(found); | ||
1931 | found = new; | ||
1932 | } | ||
1933 | return found; | ||
1934 | |||
1935 | err_out: | ||
1936 | iput(inode); | 1904 | iput(inode); |
1937 | return found; | 1905 | return found; |
1938 | } | 1906 | } |
@@ -2234,7 +2202,7 @@ int d_validate(struct dentry *dentry, struct dentry *dparent) | |||
2234 | struct dentry *child; | 2202 | struct dentry *child; |
2235 | 2203 | ||
2236 | spin_lock(&dparent->d_lock); | 2204 | spin_lock(&dparent->d_lock); |
2237 | list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) { | 2205 | list_for_each_entry(child, &dparent->d_subdirs, d_child) { |
2238 | if (dentry == child) { | 2206 | if (dentry == child) { |
2239 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); | 2207 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); |
2240 | __dget_dlock(dentry); | 2208 | __dget_dlock(dentry); |
@@ -2525,13 +2493,13 @@ static void __d_move(struct dentry *dentry, struct dentry *target, | |||
2525 | /* splicing a tree */ | 2493 | /* splicing a tree */ |
2526 | dentry->d_parent = target->d_parent; | 2494 | dentry->d_parent = target->d_parent; |
2527 | target->d_parent = target; | 2495 | target->d_parent = target; |
2528 | list_del_init(&target->d_u.d_child); | 2496 | list_del_init(&target->d_child); |
2529 | list_move(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs); | 2497 | list_move(&dentry->d_child, &dentry->d_parent->d_subdirs); |
2530 | } else { | 2498 | } else { |
2531 | /* swapping two dentries */ | 2499 | /* swapping two dentries */ |
2532 | swap(dentry->d_parent, target->d_parent); | 2500 | swap(dentry->d_parent, target->d_parent); |
2533 | list_move(&target->d_u.d_child, &target->d_parent->d_subdirs); | 2501 | list_move(&target->d_child, &target->d_parent->d_subdirs); |
2534 | list_move(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs); | 2502 | list_move(&dentry->d_child, &dentry->d_parent->d_subdirs); |
2535 | if (exchange) | 2503 | if (exchange) |
2536 | fsnotify_d_move(target); | 2504 | fsnotify_d_move(target); |
2537 | fsnotify_d_move(dentry); | 2505 | fsnotify_d_move(dentry); |
@@ -3320,7 +3288,7 @@ void d_tmpfile(struct dentry *dentry, struct inode *inode) | |||
3320 | { | 3288 | { |
3321 | inode_dec_link_count(inode); | 3289 | inode_dec_link_count(inode); |
3322 | BUG_ON(dentry->d_name.name != dentry->d_iname || | 3290 | BUG_ON(dentry->d_name.name != dentry->d_iname || |
3323 | !hlist_unhashed(&dentry->d_alias) || | 3291 | !hlist_unhashed(&dentry->d_u.d_alias) || |
3324 | !d_unlinked(dentry)); | 3292 | !d_unlinked(dentry)); |
3325 | spin_lock(&dentry->d_parent->d_lock); | 3293 | spin_lock(&dentry->d_parent->d_lock); |
3326 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); | 3294 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); |