diff options
author | Josef Bacik <josef@redhat.com> | 2011-05-31 11:58:49 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-07-20 01:43:03 -0400 |
commit | 44396f4b5cb8566f7118aec55eeac99be7ad94cb (patch) | |
tree | dc2fd0d01c634ee9a5f5cfb8ca0d660f060ce188 /include/linux/dcache.h | |
parent | e6625fa48e6580a74b7e700efd7e6463e282810b (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 'include/linux/dcache.h')
-rw-r--r-- | include/linux/dcache.h | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 19d90a55541d..5fa5bd33b979 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -216,6 +216,7 @@ struct dentry_operations { | |||
216 | #define DCACHE_MOUNTED 0x10000 /* is a mountpoint */ | 216 | #define DCACHE_MOUNTED 0x10000 /* is a mountpoint */ |
217 | #define DCACHE_NEED_AUTOMOUNT 0x20000 /* handle automount on this dir */ | 217 | #define DCACHE_NEED_AUTOMOUNT 0x20000 /* handle automount on this dir */ |
218 | #define DCACHE_MANAGE_TRANSIT 0x40000 /* manage transit from this dirent */ | 218 | #define DCACHE_MANAGE_TRANSIT 0x40000 /* manage transit from this dirent */ |
219 | #define DCACHE_NEED_LOOKUP 0x80000 /* dentry requires i_op->lookup */ | ||
219 | #define DCACHE_MANAGED_DENTRY \ | 220 | #define DCACHE_MANAGED_DENTRY \ |
220 | (DCACHE_MOUNTED|DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT) | 221 | (DCACHE_MOUNTED|DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT) |
221 | 222 | ||
@@ -416,6 +417,12 @@ static inline bool d_mountpoint(struct dentry *dentry) | |||
416 | return dentry->d_flags & DCACHE_MOUNTED; | 417 | return dentry->d_flags & DCACHE_MOUNTED; |
417 | } | 418 | } |
418 | 419 | ||
420 | static inline bool d_need_lookup(struct dentry *dentry) | ||
421 | { | ||
422 | return dentry->d_flags & DCACHE_NEED_LOOKUP; | ||
423 | } | ||
424 | |||
425 | extern void d_clear_need_lookup(struct dentry *dentry); | ||
419 | extern struct dentry *lookup_create(struct nameidata *nd, int is_dir); | 426 | extern struct dentry *lookup_create(struct nameidata *nd, int is_dir); |
420 | 427 | ||
421 | extern int sysctl_vfs_cache_pressure; | 428 | extern int sysctl_vfs_cache_pressure; |