[PATCH 3/3] Avoid doing extra 'lstat()'s for d_type if we have an up-to-date cache entry
- From
Linus Torvalds <torvalds@linux-foundation.org>
- Date
- Jul 9, 2009, 02:43 UTC
- Message-ID
- <alpine.LFD.2.01.0907081942380.3352@localhost.localdomain>
- In-Reply-To
- <alpine.LFD.2.01.0907081940220.3352@localhost.localdomain>
From: Linus Torvalds <torvalds@linux-foundation.org> Date: Wed, 8 Jul 2009 19:31:49 -0700 Subject: [PATCH 3/3] Avoid doing extra 'lstat()'s for d_type if we have an up-to-date cache entry
On filesystems without d_type, we can look at the cache entry first. Doing an lstat() can be expensive.
Reported by Dmitry Potapov for Cygwin.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> ---
This is the same patch I already sent Dmitry, but now it applies on top of the cleaned-up read_directory_recursive() code.
dir.c | 14 +++++++++----- 1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/dir.c b/dir.c index b0671f5..8a9e7d8 100644 --- a/dir.c +++ b/dir.c @@ -16,7 +16,7 @@ struct path_simplify { static int read_directory_recursive(struct dir_struct *dir, const char *path, int len, int check_only, const struct path_simplify *simplify); -static int get_dtype(struct dirent *de, const char *path); +static int get_dtype(struct dirent *de, const char *path, int len); static int common_prefix(const char **pathspec) { @@ -326,7 +326,7 @@ static int excluded_1(const char *pathname, if (x->flags & EXC_FLAG_MUSTBEDIR) { if (*dtype == DT_UNKNOWN) - *dtype = get_dtype(NULL, pathname); + *dtype = get_dtype(NULL, pathname, pathlen); if (*dtype != DT_DIR) continue; } @@ -566,14 +566,18 @@ static int in_pathspec(const char *path, int len, const struct path_simplify *si return 0; } -static int get_dtype(struct dirent *de, const char *path) +static int get_dtype(struct dirent *de, const char *path, int len) { int dtype = de ? DTYPE(de) : DT_UNKNOWN; + struct cache_entry *ce; struct stat st; if (dtype != DT_UNKNOWN) return dtype; - if (lstat(path, &st)) + ce = cache_name_exists(path, len, 0); + if (ce && ce_uptodate(ce)) + st.st_mode = ce->ce_mode; + else if (lstat(path, &st)) return dtype; if (S_ISREG(st.st_mode)) return DT_REG; @@ -633,7 +637,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *base, in continue; if (dtype == DT_UNKNOWN) - dtype = get_dtype(de, path); + dtype = get_dtype(de, path, len); /* * Do we want to see just the ignored files?
-- 1.6.3.3.412.gf581d