diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 22a0ef41bad1..fbdcbca40725 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 | /* |
@@ -1219,7 +1220,7 @@ void shrink_dcache_parent(struct dentry * parent) | |||
1219 | EXPORT_SYMBOL(shrink_dcache_parent); | 1220 | EXPORT_SYMBOL(shrink_dcache_parent); |
1220 | 1221 | ||
1221 | /* | 1222 | /* |
1222 | * Scan `nr' dentries and return the number which remain. | 1223 | * Scan `sc->nr_slab_to_reclaim' dentries and return the number which remain. |
1223 | * | 1224 | * |
1224 | * 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 |
1225 | * GFP_NOFS allocation attempt. One example deadlock is: | 1226 | * GFP_NOFS allocation attempt. One example deadlock is: |
@@ -1230,8 +1231,12 @@ EXPORT_SYMBOL(shrink_dcache_parent); | |||
1230 | * | 1231 | * |
1231 | * 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. |
1232 | */ | 1233 | */ |
1233 | 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) | ||
1234 | { | 1236 | { |
1237 | int nr = sc->nr_to_scan; | ||
1238 | gfp_t gfp_mask = sc->gfp_mask; | ||
1239 | |||
1235 | if (nr) { | 1240 | if (nr) { |
1236 | if (!(gfp_mask & __GFP_FS)) | 1241 | if (!(gfp_mask & __GFP_FS)) |
1237 | return -1; | 1242 | return -1; |
@@ -1808,8 +1813,6 @@ seqretry: | |||
1808 | tname = dentry->d_name.name; | 1813 | tname = dentry->d_name.name; |
1809 | i = dentry->d_inode; | 1814 | i = dentry->d_inode; |
1810 | prefetch(tname); | 1815 | prefetch(tname); |
1811 | if (i) | ||
1812 | prefetch(i); | ||
1813 | /* | 1816 | /* |
1814 | * This seqcount check is required to ensure name and | 1817 | * This seqcount check is required to ensure name and |
1815 | * len are loaded atomically, so as not to walk off the | 1818 | * len are loaded atomically, so as not to walk off the |
@@ -2208,14 +2211,15 @@ static void dentry_unlock_parents_for_move(struct dentry *dentry, | |||
2208 | * The hash value has to match the hash queue that the dentry is on.. | 2211 | * The hash value has to match the hash queue that the dentry is on.. |
2209 | */ | 2212 | */ |
2210 | /* | 2213 | /* |
2211 | * d_move - move a dentry | 2214 | * __d_move - move a dentry |
2212 | * @dentry: entry to move | 2215 | * @dentry: entry to move |
2213 | * @target: new dentry | 2216 | * @target: new dentry |
2214 | * | 2217 | * |
2215 | * Update the dcache to reflect the move of a file name. Negative | 2218 | * Update the dcache to reflect the move of a file name. Negative |
2216 | * dcache entries should not be moved in this way. | 2219 | * dcache entries should not be moved in this way. Caller hold |
2220 | * rename_lock. | ||
2217 | */ | 2221 | */ |
2218 | void d_move(struct dentry * dentry, struct dentry * target) | 2222 | static void __d_move(struct dentry * dentry, struct dentry * target) |
2219 | { | 2223 | { |
2220 | if (!dentry->d_inode) | 2224 | if (!dentry->d_inode) |
2221 | printk(KERN_WARNING "VFS: moving negative dcache entry\n"); | 2225 | printk(KERN_WARNING "VFS: moving negative dcache entry\n"); |
@@ -2223,8 +2227,6 @@ void d_move(struct dentry * dentry, struct dentry * target) | |||
2223 | BUG_ON(d_ancestor(dentry, target)); | 2227 | BUG_ON(d_ancestor(dentry, target)); |
2224 | BUG_ON(d_ancestor(target, dentry)); | 2228 | BUG_ON(d_ancestor(target, dentry)); |
2225 | 2229 | ||
2226 | write_seqlock(&rename_lock); | ||
2227 | |||
2228 | dentry_lock_for_move(dentry, target); | 2230 | dentry_lock_for_move(dentry, target); |
2229 | 2231 | ||
2230 | write_seqcount_begin(&dentry->d_seq); | 2232 | write_seqcount_begin(&dentry->d_seq); |
@@ -2270,6 +2272,20 @@ void d_move(struct dentry * dentry, struct dentry * target) | |||
2270 | spin_unlock(&target->d_lock); | 2272 | spin_unlock(&target->d_lock); |
2271 | fsnotify_d_move(dentry); | 2273 | fsnotify_d_move(dentry); |
2272 | spin_unlock(&dentry->d_lock); | 2274 | spin_unlock(&dentry->d_lock); |
2275 | } | ||
2276 | |||
2277 | /* | ||
2278 | * d_move - move a dentry | ||
2279 | * @dentry: entry to move | ||
2280 | * @target: new dentry | ||
2281 | * | ||
2282 | * Update the dcache to reflect the move of a file name. Negative | ||
2283 | * dcache entries should not be moved in this way. | ||
2284 | */ | ||
2285 | void d_move(struct dentry *dentry, struct dentry *target) | ||
2286 | { | ||
2287 | write_seqlock(&rename_lock); | ||
2288 | __d_move(dentry, target); | ||
2273 | write_sequnlock(&rename_lock); | 2289 | write_sequnlock(&rename_lock); |
2274 | } | 2290 | } |
2275 | EXPORT_SYMBOL(d_move); | 2291 | EXPORT_SYMBOL(d_move); |
@@ -2297,7 +2313,7 @@ struct dentry *d_ancestor(struct dentry *p1, struct dentry *p2) | |||
2297 | * This helper attempts to cope with remotely renamed directories | 2313 | * This helper attempts to cope with remotely renamed directories |
2298 | * | 2314 | * |
2299 | * It assumes that the caller is already holding | 2315 | * It assumes that the caller is already holding |
2300 | * dentry->d_parent->d_inode->i_mutex and the inode->i_lock | 2316 | * dentry->d_parent->d_inode->i_mutex, inode->i_lock and rename_lock |
2301 | * | 2317 | * |
2302 | * Note: If ever the locking in lock_rename() changes, then please | 2318 | * Note: If ever the locking in lock_rename() changes, then please |
2303 | * remember to update this too... | 2319 | * remember to update this too... |
@@ -2312,11 +2328,6 @@ static struct dentry *__d_unalias(struct inode *inode, | |||
2312 | if (alias->d_parent == dentry->d_parent) | 2328 | if (alias->d_parent == dentry->d_parent) |
2313 | goto out_unalias; | 2329 | goto out_unalias; |
2314 | 2330 | ||
2315 | /* Check for loops */ | ||
2316 | ret = ERR_PTR(-ELOOP); | ||
2317 | if (d_ancestor(alias, dentry)) | ||
2318 | goto out_err; | ||
2319 | |||
2320 | /* See lock_rename() */ | 2331 | /* See lock_rename() */ |
2321 | ret = ERR_PTR(-EBUSY); | 2332 | ret = ERR_PTR(-EBUSY); |
2322 | if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex)) | 2333 | if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex)) |
@@ -2326,7 +2337,7 @@ static struct dentry *__d_unalias(struct inode *inode, | |||
2326 | goto out_err; | 2337 | goto out_err; |
2327 | m2 = &alias->d_parent->d_inode->i_mutex; | 2338 | m2 = &alias->d_parent->d_inode->i_mutex; |
2328 | out_unalias: | 2339 | out_unalias: |
2329 | d_move(alias, dentry); | 2340 | __d_move(alias, dentry); |
2330 | ret = alias; | 2341 | ret = alias; |
2331 | out_err: | 2342 | out_err: |
2332 | spin_unlock(&inode->i_lock); | 2343 | spin_unlock(&inode->i_lock); |
@@ -2411,15 +2422,24 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) | |||
2411 | alias = __d_find_alias(inode, 0); | 2422 | alias = __d_find_alias(inode, 0); |
2412 | if (alias) { | 2423 | if (alias) { |
2413 | actual = alias; | 2424 | actual = alias; |
2414 | /* Is this an anonymous mountpoint that we could splice | 2425 | write_seqlock(&rename_lock); |
2415 | * into our tree? */ | 2426 | |
2416 | if (IS_ROOT(alias)) { | 2427 | if (d_ancestor(alias, dentry)) { |
2428 | /* Check for loops */ | ||
2429 | actual = ERR_PTR(-ELOOP); | ||
2430 | } else if (IS_ROOT(alias)) { | ||
2431 | /* Is this an anonymous mountpoint that we | ||
2432 | * could splice into our tree? */ | ||
2417 | __d_materialise_dentry(dentry, alias); | 2433 | __d_materialise_dentry(dentry, alias); |
2434 | write_sequnlock(&rename_lock); | ||
2418 | __d_drop(alias); | 2435 | __d_drop(alias); |
2419 | goto found; | 2436 | goto found; |
2437 | } else { | ||
2438 | /* Nope, but we must(!) avoid directory | ||
2439 | * aliasing */ | ||
2440 | actual = __d_unalias(inode, dentry, alias); | ||
2420 | } | 2441 | } |
2421 | /* Nope, but we must(!) avoid directory aliasing */ | 2442 | write_sequnlock(&rename_lock); |
2422 | actual = __d_unalias(inode, dentry, alias); | ||
2423 | if (IS_ERR(actual)) | 2443 | if (IS_ERR(actual)) |
2424 | dput(alias); | 2444 | dput(alias); |
2425 | goto out_nolock; | 2445 | goto out_nolock; |