Skip to content

Commit

Permalink
Avoid doing extra 'lstat()'s for d_type if we have an up-to-date cach…
Browse files Browse the repository at this point in the history
…e 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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Linus Torvalds authored and Junio C Hamano committed Jul 9, 2009
1 parent dba2e20 commit caa6b78
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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?
Expand Down

0 comments on commit caa6b78

Please sign in to comment.