diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 134 |
1 files changed, 76 insertions, 58 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 9f493ee4dcba..129a35730994 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -176,6 +176,7 @@ static void d_free(struct dentry *dentry) | |||
176 | 176 | ||
177 | /** | 177 | /** |
178 | * dentry_rcuwalk_barrier - invalidate in-progress rcu-walk lookups | 178 | * dentry_rcuwalk_barrier - invalidate in-progress rcu-walk lookups |
179 | * @dentry: the target dentry | ||
179 | * After this call, in-progress rcu-walk path lookup will fail. This | 180 | * After this call, in-progress rcu-walk path lookup will fail. This |
180 | * should be called after unhashing, and after changing d_inode (if | 181 | * should be called after unhashing, and after changing d_inode (if |
181 | * the dentry has not already been unhashed). | 182 | * the dentry has not already been unhashed). |
@@ -281,6 +282,7 @@ static void dentry_lru_move_tail(struct dentry *dentry) | |||
281 | /** | 282 | /** |
282 | * d_kill - kill dentry and return parent | 283 | * d_kill - kill dentry and return parent |
283 | * @dentry: dentry to kill | 284 | * @dentry: dentry to kill |
285 | * @parent: parent dentry | ||
284 | * | 286 | * |
285 | * The dentry must already be unhashed and removed from the LRU. | 287 | * The dentry must already be unhashed and removed from the LRU. |
286 | * | 288 | * |
@@ -294,8 +296,12 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) | |||
294 | __releases(parent->d_lock) | 296 | __releases(parent->d_lock) |
295 | __releases(dentry->d_inode->i_lock) | 297 | __releases(dentry->d_inode->i_lock) |
296 | { | 298 | { |
297 | dentry->d_parent = NULL; | ||
298 | list_del(&dentry->d_u.d_child); | 299 | list_del(&dentry->d_u.d_child); |
300 | /* | ||
301 | * Inform try_to_ascend() that we are no longer attached to the | ||
302 | * dentry tree | ||
303 | */ | ||
304 | dentry->d_flags |= DCACHE_DISCONNECTED; | ||
299 | if (parent) | 305 | if (parent) |
300 | spin_unlock(&parent->d_lock); | 306 | spin_unlock(&parent->d_lock); |
301 | dentry_iput(dentry); | 307 | dentry_iput(dentry); |
@@ -1010,6 +1016,35 @@ void shrink_dcache_for_umount(struct super_block *sb) | |||
1010 | } | 1016 | } |
1011 | 1017 | ||
1012 | /* | 1018 | /* |
1019 | * This tries to ascend one level of parenthood, but | ||
1020 | * we can race with renaming, so we need to re-check | ||
1021 | * the parenthood after dropping the lock and check | ||
1022 | * that the sequence number still matches. | ||
1023 | */ | ||
1024 | static struct dentry *try_to_ascend(struct dentry *old, int locked, unsigned seq) | ||
1025 | { | ||
1026 | struct dentry *new = old->d_parent; | ||
1027 | |||
1028 | rcu_read_lock(); | ||
1029 | spin_unlock(&old->d_lock); | ||
1030 | spin_lock(&new->d_lock); | ||
1031 | |||
1032 | /* | ||
1033 | * might go back up the wrong parent if we have had a rename | ||
1034 | * or deletion | ||
1035 | */ | ||
1036 | if (new != old->d_parent || | ||
1037 | (old->d_flags & DCACHE_DISCONNECTED) || | ||
1038 | (!locked && read_seqretry(&rename_lock, seq))) { | ||
1039 | spin_unlock(&new->d_lock); | ||
1040 | new = NULL; | ||
1041 | } | ||
1042 | rcu_read_unlock(); | ||
1043 | return new; | ||
1044 | } | ||
1045 | |||
1046 | |||
1047 | /* | ||
1013 | * Search for at least 1 mount point in the dentry's subdirs. | 1048 | * Search for at least 1 mount point in the dentry's subdirs. |
1014 | * We descend to the next level whenever the d_subdirs | 1049 | * We descend to the next level whenever the d_subdirs |
1015 | * list is non-empty and continue searching. | 1050 | * list is non-empty and continue searching. |
@@ -1064,24 +1099,10 @@ resume: | |||
1064 | * All done at this level ... ascend and resume the search. | 1099 | * All done at this level ... ascend and resume the search. |
1065 | */ | 1100 | */ |
1066 | if (this_parent != parent) { | 1101 | if (this_parent != parent) { |
1067 | struct dentry *tmp; | 1102 | struct dentry *child = this_parent; |
1068 | struct dentry *child; | 1103 | this_parent = try_to_ascend(this_parent, locked, seq); |
1069 | 1104 | if (!this_parent) | |
1070 | tmp = this_parent->d_parent; | ||
1071 | rcu_read_lock(); | ||
1072 | spin_unlock(&this_parent->d_lock); | ||
1073 | child = this_parent; | ||
1074 | this_parent = tmp; | ||
1075 | spin_lock(&this_parent->d_lock); | ||
1076 | /* might go back up the wrong parent if we have had a rename | ||
1077 | * or deletion */ | ||
1078 | if (this_parent != child->d_parent || | ||
1079 | (!locked && read_seqretry(&rename_lock, seq))) { | ||
1080 | spin_unlock(&this_parent->d_lock); | ||
1081 | rcu_read_unlock(); | ||
1082 | goto rename_retry; | 1105 | goto rename_retry; |
1083 | } | ||
1084 | rcu_read_unlock(); | ||
1085 | next = child->d_u.d_child.next; | 1106 | next = child->d_u.d_child.next; |
1086 | goto resume; | 1107 | goto resume; |
1087 | } | 1108 | } |
@@ -1179,24 +1200,10 @@ resume: | |||
1179 | * All done at this level ... ascend and resume the search. | 1200 | * All done at this level ... ascend and resume the search. |
1180 | */ | 1201 | */ |
1181 | if (this_parent != parent) { | 1202 | if (this_parent != parent) { |
1182 | struct dentry *tmp; | 1203 | struct dentry *child = this_parent; |
1183 | struct dentry *child; | 1204 | this_parent = try_to_ascend(this_parent, locked, seq); |
1184 | 1205 | if (!this_parent) | |
1185 | tmp = this_parent->d_parent; | ||
1186 | rcu_read_lock(); | ||
1187 | spin_unlock(&this_parent->d_lock); | ||
1188 | child = this_parent; | ||
1189 | this_parent = tmp; | ||
1190 | spin_lock(&this_parent->d_lock); | ||
1191 | /* might go back up the wrong parent if we have had a rename | ||
1192 | * or deletion */ | ||
1193 | if (this_parent != child->d_parent || | ||
1194 | (!locked && read_seqretry(&rename_lock, seq))) { | ||
1195 | spin_unlock(&this_parent->d_lock); | ||
1196 | rcu_read_unlock(); | ||
1197 | goto rename_retry; | 1206 | goto rename_retry; |
1198 | } | ||
1199 | rcu_read_unlock(); | ||
1200 | next = child->d_u.d_child.next; | 1207 | next = child->d_u.d_child.next; |
1201 | goto resume; | 1208 | goto resume; |
1202 | } | 1209 | } |
@@ -1521,6 +1528,28 @@ struct dentry * d_alloc_root(struct inode * root_inode) | |||
1521 | } | 1528 | } |
1522 | EXPORT_SYMBOL(d_alloc_root); | 1529 | EXPORT_SYMBOL(d_alloc_root); |
1523 | 1530 | ||
1531 | static struct dentry * __d_find_any_alias(struct inode *inode) | ||
1532 | { | ||
1533 | struct dentry *alias; | ||
1534 | |||
1535 | if (list_empty(&inode->i_dentry)) | ||
1536 | return NULL; | ||
1537 | alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias); | ||
1538 | __dget(alias); | ||
1539 | return alias; | ||
1540 | } | ||
1541 | |||
1542 | static struct dentry * d_find_any_alias(struct inode *inode) | ||
1543 | { | ||
1544 | struct dentry *de; | ||
1545 | |||
1546 | spin_lock(&inode->i_lock); | ||
1547 | de = __d_find_any_alias(inode); | ||
1548 | spin_unlock(&inode->i_lock); | ||
1549 | return de; | ||
1550 | } | ||
1551 | |||
1552 | |||
1524 | /** | 1553 | /** |
1525 | * d_obtain_alias - find or allocate a dentry for a given inode | 1554 | * d_obtain_alias - find or allocate a dentry for a given inode |
1526 | * @inode: inode to allocate the dentry for | 1555 | * @inode: inode to allocate the dentry for |
@@ -1550,7 +1579,7 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1550 | if (IS_ERR(inode)) | 1579 | if (IS_ERR(inode)) |
1551 | return ERR_CAST(inode); | 1580 | return ERR_CAST(inode); |
1552 | 1581 | ||
1553 | res = d_find_alias(inode); | 1582 | res = d_find_any_alias(inode); |
1554 | if (res) | 1583 | if (res) |
1555 | goto out_iput; | 1584 | goto out_iput; |
1556 | 1585 | ||
@@ -1563,7 +1592,7 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1563 | 1592 | ||
1564 | 1593 | ||
1565 | spin_lock(&inode->i_lock); | 1594 | spin_lock(&inode->i_lock); |
1566 | res = __d_find_alias(inode, 0); | 1595 | res = __d_find_any_alias(inode); |
1567 | if (res) { | 1596 | if (res) { |
1568 | spin_unlock(&inode->i_lock); | 1597 | spin_unlock(&inode->i_lock); |
1569 | dput(tmp); | 1598 | dput(tmp); |
@@ -1583,10 +1612,13 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1583 | __bit_spin_unlock(0, (unsigned long *)&tmp->d_sb->s_anon.first); | 1612 | __bit_spin_unlock(0, (unsigned long *)&tmp->d_sb->s_anon.first); |
1584 | spin_unlock(&tmp->d_lock); | 1613 | spin_unlock(&tmp->d_lock); |
1585 | spin_unlock(&inode->i_lock); | 1614 | spin_unlock(&inode->i_lock); |
1615 | security_d_instantiate(tmp, inode); | ||
1586 | 1616 | ||
1587 | return tmp; | 1617 | return tmp; |
1588 | 1618 | ||
1589 | out_iput: | 1619 | out_iput: |
1620 | if (res && !IS_ERR(res)) | ||
1621 | security_d_instantiate(res, inode); | ||
1590 | iput(inode); | 1622 | iput(inode); |
1591 | return res; | 1623 | return res; |
1592 | } | 1624 | } |
@@ -1779,7 +1811,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, | |||
1779 | * false-negative result. d_lookup() protects against concurrent | 1811 | * false-negative result. d_lookup() protects against concurrent |
1780 | * renames using rename_lock seqlock. | 1812 | * renames using rename_lock seqlock. |
1781 | * | 1813 | * |
1782 | * See Documentation/vfs/dcache-locking.txt for more details. | 1814 | * See Documentation/filesystems/path-lookup.txt for more details. |
1783 | */ | 1815 | */ |
1784 | hlist_bl_for_each_entry_rcu(dentry, node, &b->head, d_hash) { | 1816 | hlist_bl_for_each_entry_rcu(dentry, node, &b->head, d_hash) { |
1785 | struct inode *i; | 1817 | struct inode *i; |
@@ -1899,7 +1931,7 @@ struct dentry *__d_lookup(struct dentry *parent, struct qstr *name) | |||
1899 | * false-negative result. d_lookup() protects against concurrent | 1931 | * false-negative result. d_lookup() protects against concurrent |
1900 | * renames using rename_lock seqlock. | 1932 | * renames using rename_lock seqlock. |
1901 | * | 1933 | * |
1902 | * See Documentation/vfs/dcache-locking.txt for more details. | 1934 | * See Documentation/filesystems/path-lookup.txt for more details. |
1903 | */ | 1935 | */ |
1904 | rcu_read_lock(); | 1936 | rcu_read_lock(); |
1905 | 1937 | ||
@@ -1973,7 +2005,7 @@ out: | |||
1973 | /** | 2005 | /** |
1974 | * d_validate - verify dentry provided from insecure source (deprecated) | 2006 | * d_validate - verify dentry provided from insecure source (deprecated) |
1975 | * @dentry: The dentry alleged to be valid child of @dparent | 2007 | * @dentry: The dentry alleged to be valid child of @dparent |
1976 | * @parent: The parent dentry (known to be valid) | 2008 | * @dparent: The parent dentry (known to be valid) |
1977 | * | 2009 | * |
1978 | * An insecure source has sent us a dentry, here we verify it and dget() it. | 2010 | * An insecure source has sent us a dentry, here we verify it and dget() it. |
1979 | * This is used by ncpfs in its readdir implementation. | 2011 | * This is used by ncpfs in its readdir implementation. |
@@ -2099,7 +2131,7 @@ EXPORT_SYMBOL(d_rehash); | |||
2099 | */ | 2131 | */ |
2100 | void dentry_update_name_case(struct dentry *dentry, struct qstr *name) | 2132 | void dentry_update_name_case(struct dentry *dentry, struct qstr *name) |
2101 | { | 2133 | { |
2102 | BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex)); | 2134 | BUG_ON(!mutex_is_locked(&dentry->d_parent->d_inode->i_mutex)); |
2103 | BUG_ON(dentry->d_name.len != name->len); /* d_lookup gives this */ | 2135 | BUG_ON(dentry->d_name.len != name->len); /* d_lookup gives this */ |
2104 | 2136 | ||
2105 | spin_lock(&dentry->d_lock); | 2137 | spin_lock(&dentry->d_lock); |
@@ -2918,28 +2950,14 @@ resume: | |||
2918 | spin_unlock(&dentry->d_lock); | 2950 | spin_unlock(&dentry->d_lock); |
2919 | } | 2951 | } |
2920 | if (this_parent != root) { | 2952 | if (this_parent != root) { |
2921 | struct dentry *tmp; | 2953 | struct dentry *child = this_parent; |
2922 | struct dentry *child; | ||
2923 | |||
2924 | tmp = this_parent->d_parent; | ||
2925 | if (!(this_parent->d_flags & DCACHE_GENOCIDE)) { | 2954 | if (!(this_parent->d_flags & DCACHE_GENOCIDE)) { |
2926 | this_parent->d_flags |= DCACHE_GENOCIDE; | 2955 | this_parent->d_flags |= DCACHE_GENOCIDE; |
2927 | this_parent->d_count--; | 2956 | this_parent->d_count--; |
2928 | } | 2957 | } |
2929 | rcu_read_lock(); | 2958 | this_parent = try_to_ascend(this_parent, locked, seq); |
2930 | spin_unlock(&this_parent->d_lock); | 2959 | if (!this_parent) |
2931 | child = this_parent; | ||
2932 | this_parent = tmp; | ||
2933 | spin_lock(&this_parent->d_lock); | ||
2934 | /* might go back up the wrong parent if we have had a rename | ||
2935 | * or deletion */ | ||
2936 | if (this_parent != child->d_parent || | ||
2937 | (!locked && read_seqretry(&rename_lock, seq))) { | ||
2938 | spin_unlock(&this_parent->d_lock); | ||
2939 | rcu_read_unlock(); | ||
2940 | goto rename_retry; | 2960 | goto rename_retry; |
2941 | } | ||
2942 | rcu_read_unlock(); | ||
2943 | next = child->d_u.d_child.next; | 2961 | next = child->d_u.d_child.next; |
2944 | goto resume; | 2962 | goto resume; |
2945 | } | 2963 | } |