aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c62
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)
1219EXPORT_SYMBOL(shrink_dcache_parent); 1220EXPORT_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 */
1233static int shrink_dcache_memory(struct shrinker *shrink, int nr, gfp_t gfp_mask) 1234static 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 */
2218void d_move(struct dentry * dentry, struct dentry * target) 2222static 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 */
2285void 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}
2275EXPORT_SYMBOL(d_move); 2291EXPORT_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;
2328out_unalias: 2339out_unalias:
2329 d_move(alias, dentry); 2340 __d_move(alias, dentry);
2330 ret = alias; 2341 ret = alias;
2331out_err: 2342out_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;