Skip to content

Commit caa6b78

Browse files
torvaldsgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent dba2e20 commit caa6b78

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

dir.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ struct path_simplify {
1616

1717
static int read_directory_recursive(struct dir_struct *dir, const char *path, int len,
1818
int check_only, const struct path_simplify *simplify);
19-
static int get_dtype(struct dirent *de, const char *path);
19+
static int get_dtype(struct dirent *de, const char *path, int len);
2020

2121
static int common_prefix(const char **pathspec)
2222
{
@@ -326,7 +326,7 @@ static int excluded_1(const char *pathname,
326326

327327
if (x->flags & EXC_FLAG_MUSTBEDIR) {
328328
if (*dtype == DT_UNKNOWN)
329-
*dtype = get_dtype(NULL, pathname);
329+
*dtype = get_dtype(NULL, pathname, pathlen);
330330
if (*dtype != DT_DIR)
331331
continue;
332332
}
@@ -566,14 +566,18 @@ static int in_pathspec(const char *path, int len, const struct path_simplify *si
566566
return 0;
567567
}
568568

569-
static int get_dtype(struct dirent *de, const char *path)
569+
static int get_dtype(struct dirent *de, const char *path, int len)
570570
{
571571
int dtype = de ? DTYPE(de) : DT_UNKNOWN;
572+
struct cache_entry *ce;
572573
struct stat st;
573574

574575
if (dtype != DT_UNKNOWN)
575576
return dtype;
576-
if (lstat(path, &st))
577+
ce = cache_name_exists(path, len, 0);
578+
if (ce && ce_uptodate(ce))
579+
st.st_mode = ce->ce_mode;
580+
else if (lstat(path, &st))
577581
return dtype;
578582
if (S_ISREG(st.st_mode))
579583
return DT_REG;
@@ -633,7 +637,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *base, in
633637
continue;
634638

635639
if (dtype == DT_UNKNOWN)
636-
dtype = get_dtype(de, path);
640+
dtype = get_dtype(de, path, len);
637641

638642
/*
639643
* Do we want to see just the ignored files?

0 commit comments

Comments
 (0)