aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-05-31 11:58:49 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-07-20 01:43:03 -0400
commit44396f4b5cb8566f7118aec55eeac99be7ad94cb (patch)
treedc2fd0d01c634ee9a5f5cfb8ca0d660f060ce188 /fs/dcache.c
parente6625fa48e6580a74b7e700efd7e6463e282810b (diff)
fs: add a DCACHE_NEED_LOOKUP flag for d_flags
Btrfs (and I'd venture most other fs's) stores its indexes in nice disk order for readdir, but unfortunately in the case of anything that stats the files in order that readdir spits back (like oh say ls) that means we still have to do the normal lookup of the file, which means looking up our other index and then looking up the inode. What I want is a way to create dummy dentries when we find them in readdir so that when ls or anything else subsequently does a stat(), we already have the location information in the dentry and can go straight to the inode itself. The lookup stuff just assumes that if it finds a dentry it is done, it doesn't perform a lookup. So add a DCACHE_NEED_LOOKUP flag so that the lookup code knows it still needs to run i_op->lookup() on the parent to get the inode for the dentry. I have tested this with btrfs and I went from something that looks like this http://people.redhat.com/jwhiter/ls-noreada.png To this http://people.redhat.com/jwhiter/ls-good.png Thats a savings of 1300 seconds, or 22 minutes. That is a significant savings. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 6e4ea6d87774..d3902139b533 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -344,6 +344,24 @@ void d_drop(struct dentry *dentry)
344EXPORT_SYMBOL(d_drop); 344EXPORT_SYMBOL(d_drop);
345 345
346/* 346/*
347 * d_clear_need_lookup - drop a dentry from cache and clear the need lookup flag
348 * @dentry: dentry to drop
349 *
350 * This is called when we do a lookup on a placeholder dentry that needed to be
351 * looked up. The dentry should have been hashed in order for it to be found by
352 * the lookup code, but now needs to be unhashed while we do the actual lookup
353 * and clear the DCACHE_NEED_LOOKUP flag.
354 */
355void d_clear_need_lookup(struct dentry *dentry)
356{
357 spin_lock(&dentry->d_lock);
358 __d_drop(dentry);
359 dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
360 spin_unlock(&dentry->d_lock);
361}
362EXPORT_SYMBOL(d_clear_need_lookup);
363
364/*
347 * Finish off a dentry we've decided to kill. 365 * Finish off a dentry we've decided to kill.
348 * dentry->d_lock must be held, returns with it unlocked. 366 * dentry->d_lock must be held, returns with it unlocked.
349 * If ref is non-zero, then decrement the refcount too. 367 * If ref is non-zero, then decrement the refcount too.
@@ -432,8 +450,13 @@ repeat:
432 if (d_unhashed(dentry)) 450 if (d_unhashed(dentry))
433 goto kill_it; 451 goto kill_it;
434 452
435 /* Otherwise leave it cached and ensure it's on the LRU */ 453 /*
436 dentry->d_flags |= DCACHE_REFERENCED; 454 * If this dentry needs lookup, don't set the referenced flag so that it
455 * is more likely to be cleaned up by the dcache shrinker in case of
456 * memory pressure.
457 */
458 if (!d_need_lookup(dentry))
459 dentry->d_flags |= DCACHE_REFERENCED;
437 dentry_lru_add(dentry); 460 dentry_lru_add(dentry);
438 461
439 dentry->d_count--; 462 dentry->d_count--;
@@ -1708,6 +1731,13 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
1708 } 1731 }
1709 1732
1710 /* 1733 /*
1734 * We are going to instantiate this dentry, unhash it and clear the
1735 * lookup flag so we can do that.
1736 */
1737 if (unlikely(d_need_lookup(found)))
1738 d_clear_need_lookup(found);
1739
1740 /*
1711 * Negative dentry: instantiate it unless the inode is a directory and 1741 * Negative dentry: instantiate it unless the inode is a directory and
1712 * already has a dentry. 1742 * already has a dentry.
1713 */ 1743 */