diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 184 |
1 files changed, 94 insertions, 90 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index e7a1a99b7464..a1d86c7f3e66 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -69,6 +69,7 @@ struct dentry_stat_t dentry_stat = { | |||
69 | 69 | ||
70 | static void __d_free(struct dentry *dentry) | 70 | static void __d_free(struct dentry *dentry) |
71 | { | 71 | { |
72 | WARN_ON(!list_empty(&dentry->d_alias)); | ||
72 | if (dname_external(dentry)) | 73 | if (dname_external(dentry)) |
73 | kfree(dentry->d_name.name); | 74 | kfree(dentry->d_name.name); |
74 | kmem_cache_free(dentry_cache, dentry); | 75 | kmem_cache_free(dentry_cache, dentry); |
@@ -174,9 +175,12 @@ static struct dentry *d_kill(struct dentry *dentry) | |||
174 | dentry_stat.nr_dentry--; /* For d_free, below */ | 175 | dentry_stat.nr_dentry--; /* For d_free, below */ |
175 | /*drops the locks, at that point nobody can reach this dentry */ | 176 | /*drops the locks, at that point nobody can reach this dentry */ |
176 | dentry_iput(dentry); | 177 | dentry_iput(dentry); |
177 | parent = dentry->d_parent; | 178 | if (IS_ROOT(dentry)) |
179 | parent = NULL; | ||
180 | else | ||
181 | parent = dentry->d_parent; | ||
178 | d_free(dentry); | 182 | d_free(dentry); |
179 | return dentry == parent ? NULL : parent; | 183 | return parent; |
180 | } | 184 | } |
181 | 185 | ||
182 | /* | 186 | /* |
@@ -666,11 +670,12 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) | |||
666 | BUG(); | 670 | BUG(); |
667 | } | 671 | } |
668 | 672 | ||
669 | parent = dentry->d_parent; | 673 | if (IS_ROOT(dentry)) |
670 | if (parent == dentry) | ||
671 | parent = NULL; | 674 | parent = NULL; |
672 | else | 675 | else { |
676 | parent = dentry->d_parent; | ||
673 | atomic_dec(&parent->d_count); | 677 | atomic_dec(&parent->d_count); |
678 | } | ||
674 | 679 | ||
675 | list_del(&dentry->d_u.d_child); | 680 | list_del(&dentry->d_u.d_child); |
676 | detached++; | 681 | detached++; |
@@ -977,6 +982,15 @@ struct dentry *d_alloc_name(struct dentry *parent, const char *name) | |||
977 | return d_alloc(parent, &q); | 982 | return d_alloc(parent, &q); |
978 | } | 983 | } |
979 | 984 | ||
985 | /* the caller must hold dcache_lock */ | ||
986 | static void __d_instantiate(struct dentry *dentry, struct inode *inode) | ||
987 | { | ||
988 | if (inode) | ||
989 | list_add(&dentry->d_alias, &inode->i_dentry); | ||
990 | dentry->d_inode = inode; | ||
991 | fsnotify_d_instantiate(dentry, inode); | ||
992 | } | ||
993 | |||
980 | /** | 994 | /** |
981 | * d_instantiate - fill in inode information for a dentry | 995 | * d_instantiate - fill in inode information for a dentry |
982 | * @entry: dentry to complete | 996 | * @entry: dentry to complete |
@@ -996,10 +1010,7 @@ void d_instantiate(struct dentry *entry, struct inode * inode) | |||
996 | { | 1010 | { |
997 | BUG_ON(!list_empty(&entry->d_alias)); | 1011 | BUG_ON(!list_empty(&entry->d_alias)); |
998 | spin_lock(&dcache_lock); | 1012 | spin_lock(&dcache_lock); |
999 | if (inode) | 1013 | __d_instantiate(entry, inode); |
1000 | list_add(&entry->d_alias, &inode->i_dentry); | ||
1001 | entry->d_inode = inode; | ||
1002 | fsnotify_d_instantiate(entry, inode); | ||
1003 | spin_unlock(&dcache_lock); | 1014 | spin_unlock(&dcache_lock); |
1004 | security_d_instantiate(entry, inode); | 1015 | security_d_instantiate(entry, inode); |
1005 | } | 1016 | } |
@@ -1029,7 +1040,7 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry, | |||
1029 | unsigned int hash = entry->d_name.hash; | 1040 | unsigned int hash = entry->d_name.hash; |
1030 | 1041 | ||
1031 | if (!inode) { | 1042 | if (!inode) { |
1032 | entry->d_inode = NULL; | 1043 | __d_instantiate(entry, NULL); |
1033 | return NULL; | 1044 | return NULL; |
1034 | } | 1045 | } |
1035 | 1046 | ||
@@ -1048,9 +1059,7 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry, | |||
1048 | return alias; | 1059 | return alias; |
1049 | } | 1060 | } |
1050 | 1061 | ||
1051 | list_add(&entry->d_alias, &inode->i_dentry); | 1062 | __d_instantiate(entry, inode); |
1052 | entry->d_inode = inode; | ||
1053 | fsnotify_d_instantiate(entry, inode); | ||
1054 | return NULL; | 1063 | return NULL; |
1055 | } | 1064 | } |
1056 | 1065 | ||
@@ -1111,69 +1120,71 @@ static inline struct hlist_head *d_hash(struct dentry *parent, | |||
1111 | } | 1120 | } |
1112 | 1121 | ||
1113 | /** | 1122 | /** |
1114 | * d_alloc_anon - allocate an anonymous dentry | 1123 | * d_obtain_alias - find or allocate a dentry for a given inode |
1115 | * @inode: inode to allocate the dentry for | 1124 | * @inode: inode to allocate the dentry for |
1116 | * | 1125 | * |
1117 | * This is similar to d_alloc_root. It is used by filesystems when | 1126 | * Obtain a dentry for an inode resulting from NFS filehandle conversion or |
1118 | * creating a dentry for a given inode, often in the process of | 1127 | * similar open by handle operations. The returned dentry may be anonymous, |
1119 | * mapping a filehandle to a dentry. The returned dentry may be | 1128 | * or may have a full name (if the inode was already in the cache). |
1120 | * anonymous, or may have a full name (if the inode was already | ||
1121 | * in the cache). The file system may need to make further | ||
1122 | * efforts to connect this dentry into the dcache properly. | ||
1123 | * | 1129 | * |
1124 | * When called on a directory inode, we must ensure that | 1130 | * When called on a directory inode, we must ensure that the inode only ever |
1125 | * the inode only ever has one dentry. If a dentry is | 1131 | * has one dentry. If a dentry is found, that is returned instead of |
1126 | * found, that is returned instead of allocating a new one. | 1132 | * allocating a new one. |
1127 | * | 1133 | * |
1128 | * On successful return, the reference to the inode has been transferred | 1134 | * On successful return, the reference to the inode has been transferred |
1129 | * to the dentry. If %NULL is returned (indicating kmalloc failure), | 1135 | * to the dentry. In case of an error the reference on the inode is released. |
1130 | * the reference on the inode has not been released. | 1136 | * To make it easier to use in export operations a %NULL or IS_ERR inode may |
1137 | * be passed in and will be the error will be propagate to the return value, | ||
1138 | * with a %NULL @inode replaced by ERR_PTR(-ESTALE). | ||
1131 | */ | 1139 | */ |
1132 | 1140 | struct dentry *d_obtain_alias(struct inode *inode) | |
1133 | struct dentry * d_alloc_anon(struct inode *inode) | ||
1134 | { | 1141 | { |
1135 | static const struct qstr anonstring = { .name = "" }; | 1142 | static const struct qstr anonstring = { .name = "" }; |
1136 | struct dentry *tmp; | 1143 | struct dentry *tmp; |
1137 | struct dentry *res; | 1144 | struct dentry *res; |
1138 | 1145 | ||
1139 | if ((res = d_find_alias(inode))) { | 1146 | if (!inode) |
1140 | iput(inode); | 1147 | return ERR_PTR(-ESTALE); |
1141 | return res; | 1148 | if (IS_ERR(inode)) |
1142 | } | 1149 | return ERR_CAST(inode); |
1143 | 1150 | ||
1144 | tmp = d_alloc(NULL, &anonstring); | 1151 | res = d_find_alias(inode); |
1145 | if (!tmp) | 1152 | if (res) |
1146 | return NULL; | 1153 | goto out_iput; |
1147 | 1154 | ||
1155 | tmp = d_alloc(NULL, &anonstring); | ||
1156 | if (!tmp) { | ||
1157 | res = ERR_PTR(-ENOMEM); | ||
1158 | goto out_iput; | ||
1159 | } | ||
1148 | tmp->d_parent = tmp; /* make sure dput doesn't croak */ | 1160 | tmp->d_parent = tmp; /* make sure dput doesn't croak */ |
1149 | 1161 | ||
1150 | spin_lock(&dcache_lock); | 1162 | spin_lock(&dcache_lock); |
1151 | res = __d_find_alias(inode, 0); | 1163 | res = __d_find_alias(inode, 0); |
1152 | if (!res) { | 1164 | if (res) { |
1153 | /* attach a disconnected dentry */ | 1165 | spin_unlock(&dcache_lock); |
1154 | res = tmp; | 1166 | dput(tmp); |
1155 | tmp = NULL; | 1167 | goto out_iput; |
1156 | spin_lock(&res->d_lock); | ||
1157 | res->d_sb = inode->i_sb; | ||
1158 | res->d_parent = res; | ||
1159 | res->d_inode = inode; | ||
1160 | res->d_flags |= DCACHE_DISCONNECTED; | ||
1161 | res->d_flags &= ~DCACHE_UNHASHED; | ||
1162 | list_add(&res->d_alias, &inode->i_dentry); | ||
1163 | hlist_add_head(&res->d_hash, &inode->i_sb->s_anon); | ||
1164 | spin_unlock(&res->d_lock); | ||
1165 | |||
1166 | inode = NULL; /* don't drop reference */ | ||
1167 | } | 1168 | } |
1169 | |||
1170 | /* attach a disconnected dentry */ | ||
1171 | spin_lock(&tmp->d_lock); | ||
1172 | tmp->d_sb = inode->i_sb; | ||
1173 | tmp->d_inode = inode; | ||
1174 | tmp->d_flags |= DCACHE_DISCONNECTED; | ||
1175 | tmp->d_flags &= ~DCACHE_UNHASHED; | ||
1176 | list_add(&tmp->d_alias, &inode->i_dentry); | ||
1177 | hlist_add_head(&tmp->d_hash, &inode->i_sb->s_anon); | ||
1178 | spin_unlock(&tmp->d_lock); | ||
1179 | |||
1168 | spin_unlock(&dcache_lock); | 1180 | spin_unlock(&dcache_lock); |
1181 | return tmp; | ||
1169 | 1182 | ||
1170 | if (inode) | 1183 | out_iput: |
1171 | iput(inode); | 1184 | iput(inode); |
1172 | if (tmp) | ||
1173 | dput(tmp); | ||
1174 | return res; | 1185 | return res; |
1175 | } | 1186 | } |
1176 | 1187 | EXPORT_SYMBOL_GPL(d_obtain_alias); | |
1177 | 1188 | ||
1178 | /** | 1189 | /** |
1179 | * d_splice_alias - splice a disconnected dentry into the tree if one exists | 1190 | * d_splice_alias - splice a disconnected dentry into the tree if one exists |
@@ -1200,17 +1211,14 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) | |||
1200 | new = __d_find_alias(inode, 1); | 1211 | new = __d_find_alias(inode, 1); |
1201 | if (new) { | 1212 | if (new) { |
1202 | BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED)); | 1213 | BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED)); |
1203 | fsnotify_d_instantiate(new, inode); | ||
1204 | spin_unlock(&dcache_lock); | 1214 | spin_unlock(&dcache_lock); |
1205 | security_d_instantiate(new, inode); | 1215 | security_d_instantiate(new, inode); |
1206 | d_rehash(dentry); | 1216 | d_rehash(dentry); |
1207 | d_move(new, dentry); | 1217 | d_move(new, dentry); |
1208 | iput(inode); | 1218 | iput(inode); |
1209 | } else { | 1219 | } else { |
1210 | /* d_instantiate takes dcache_lock, so we do it by hand */ | 1220 | /* already taking dcache_lock, so d_add() by hand */ |
1211 | list_add(&dentry->d_alias, &inode->i_dentry); | 1221 | __d_instantiate(dentry, inode); |
1212 | dentry->d_inode = inode; | ||
1213 | fsnotify_d_instantiate(dentry, inode); | ||
1214 | spin_unlock(&dcache_lock); | 1222 | spin_unlock(&dcache_lock); |
1215 | security_d_instantiate(dentry, inode); | 1223 | security_d_instantiate(dentry, inode); |
1216 | d_rehash(dentry); | 1224 | d_rehash(dentry); |
@@ -1293,8 +1301,7 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, | |||
1293 | * d_instantiate() by hand because it takes dcache_lock which | 1301 | * d_instantiate() by hand because it takes dcache_lock which |
1294 | * we already hold. | 1302 | * we already hold. |
1295 | */ | 1303 | */ |
1296 | list_add(&found->d_alias, &inode->i_dentry); | 1304 | __d_instantiate(found, inode); |
1297 | found->d_inode = inode; | ||
1298 | spin_unlock(&dcache_lock); | 1305 | spin_unlock(&dcache_lock); |
1299 | security_d_instantiate(found, inode); | 1306 | security_d_instantiate(found, inode); |
1300 | return found; | 1307 | return found; |
@@ -1456,8 +1463,6 @@ out: | |||
1456 | * d_validate - verify dentry provided from insecure source | 1463 | * d_validate - verify dentry provided from insecure source |
1457 | * @dentry: The dentry alleged to be valid child of @dparent | 1464 | * @dentry: The dentry alleged to be valid child of @dparent |
1458 | * @dparent: The parent dentry (known to be valid) | 1465 | * @dparent: The parent dentry (known to be valid) |
1459 | * @hash: Hash of the dentry | ||
1460 | * @len: Length of the name | ||
1461 | * | 1466 | * |
1462 | * An insecure source has sent us a dentry, here we verify it and dget() it. | 1467 | * An insecure source has sent us a dentry, here we verify it and dget() it. |
1463 | * This is used by ncpfs in its readdir implementation. | 1468 | * This is used by ncpfs in its readdir implementation. |
@@ -1714,18 +1719,23 @@ void d_move(struct dentry * dentry, struct dentry * target) | |||
1714 | spin_unlock(&dcache_lock); | 1719 | spin_unlock(&dcache_lock); |
1715 | } | 1720 | } |
1716 | 1721 | ||
1717 | /* | 1722 | /** |
1718 | * Helper that returns 1 if p1 is a parent of p2, else 0 | 1723 | * d_ancestor - search for an ancestor |
1724 | * @p1: ancestor dentry | ||
1725 | * @p2: child dentry | ||
1726 | * | ||
1727 | * Returns the ancestor dentry of p2 which is a child of p1, if p1 is | ||
1728 | * an ancestor of p2, else NULL. | ||
1719 | */ | 1729 | */ |
1720 | static int d_isparent(struct dentry *p1, struct dentry *p2) | 1730 | struct dentry *d_ancestor(struct dentry *p1, struct dentry *p2) |
1721 | { | 1731 | { |
1722 | struct dentry *p; | 1732 | struct dentry *p; |
1723 | 1733 | ||
1724 | for (p = p2; p->d_parent != p; p = p->d_parent) { | 1734 | for (p = p2; !IS_ROOT(p); p = p->d_parent) { |
1725 | if (p->d_parent == p1) | 1735 | if (p->d_parent == p1) |
1726 | return 1; | 1736 | return p; |
1727 | } | 1737 | } |
1728 | return 0; | 1738 | return NULL; |
1729 | } | 1739 | } |
1730 | 1740 | ||
1731 | /* | 1741 | /* |
@@ -1749,7 +1759,7 @@ static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias) | |||
1749 | 1759 | ||
1750 | /* Check for loops */ | 1760 | /* Check for loops */ |
1751 | ret = ERR_PTR(-ELOOP); | 1761 | ret = ERR_PTR(-ELOOP); |
1752 | if (d_isparent(alias, dentry)) | 1762 | if (d_ancestor(alias, dentry)) |
1753 | goto out_err; | 1763 | goto out_err; |
1754 | 1764 | ||
1755 | /* See lock_rename() */ | 1765 | /* See lock_rename() */ |
@@ -1822,7 +1832,7 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) | |||
1822 | 1832 | ||
1823 | if (!inode) { | 1833 | if (!inode) { |
1824 | actual = dentry; | 1834 | actual = dentry; |
1825 | dentry->d_inode = NULL; | 1835 | __d_instantiate(dentry, NULL); |
1826 | goto found_lock; | 1836 | goto found_lock; |
1827 | } | 1837 | } |
1828 | 1838 | ||
@@ -2149,32 +2159,27 @@ out: | |||
2149 | * Caller must ensure that "new_dentry" is pinned before calling is_subdir() | 2159 | * Caller must ensure that "new_dentry" is pinned before calling is_subdir() |
2150 | */ | 2160 | */ |
2151 | 2161 | ||
2152 | int is_subdir(struct dentry * new_dentry, struct dentry * old_dentry) | 2162 | int is_subdir(struct dentry *new_dentry, struct dentry *old_dentry) |
2153 | { | 2163 | { |
2154 | int result; | 2164 | int result; |
2155 | struct dentry * saved = new_dentry; | ||
2156 | unsigned long seq; | 2165 | unsigned long seq; |
2157 | 2166 | ||
2158 | /* need rcu_readlock to protect against the d_parent trashing due to | 2167 | /* FIXME: This is old behavior, needed? Please check callers. */ |
2159 | * d_move | 2168 | if (new_dentry == old_dentry) |
2169 | return 1; | ||
2170 | |||
2171 | /* | ||
2172 | * Need rcu_readlock to protect against the d_parent trashing | ||
2173 | * due to d_move | ||
2160 | */ | 2174 | */ |
2161 | rcu_read_lock(); | 2175 | rcu_read_lock(); |
2162 | do { | 2176 | do { |
2163 | /* for restarting inner loop in case of seq retry */ | 2177 | /* for restarting inner loop in case of seq retry */ |
2164 | new_dentry = saved; | ||
2165 | result = 0; | ||
2166 | seq = read_seqbegin(&rename_lock); | 2178 | seq = read_seqbegin(&rename_lock); |
2167 | for (;;) { | 2179 | if (d_ancestor(old_dentry, new_dentry)) |
2168 | if (new_dentry != old_dentry) { | ||
2169 | struct dentry * parent = new_dentry->d_parent; | ||
2170 | if (parent == new_dentry) | ||
2171 | break; | ||
2172 | new_dentry = parent; | ||
2173 | continue; | ||
2174 | } | ||
2175 | result = 1; | 2180 | result = 1; |
2176 | break; | 2181 | else |
2177 | } | 2182 | result = 0; |
2178 | } while (read_seqretry(&rename_lock, seq)); | 2183 | } while (read_seqretry(&rename_lock, seq)); |
2179 | rcu_read_unlock(); | 2184 | rcu_read_unlock(); |
2180 | 2185 | ||
@@ -2344,7 +2349,6 @@ void __init vfs_caches_init(unsigned long mempages) | |||
2344 | } | 2349 | } |
2345 | 2350 | ||
2346 | EXPORT_SYMBOL(d_alloc); | 2351 | EXPORT_SYMBOL(d_alloc); |
2347 | EXPORT_SYMBOL(d_alloc_anon); | ||
2348 | EXPORT_SYMBOL(d_alloc_root); | 2352 | EXPORT_SYMBOL(d_alloc_root); |
2349 | EXPORT_SYMBOL(d_delete); | 2353 | EXPORT_SYMBOL(d_delete); |
2350 | EXPORT_SYMBOL(d_find_alias); | 2354 | EXPORT_SYMBOL(d_find_alias); |