@matheusbsbs / matheus-bagliano / commits / caa6b7825a
Fork 0

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> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Linus Torvalds committed Jul 8, 2009 at 19:31 UTC caa6b7825aaddb8a97a5b793ca61df0c1ec9b76b
1 file changed +9 -5
dir.c
+9 -5
@@ -16,7 +16,7 @@ struct path_simplify {
16
17 static int read_directory_recursive(struct dir_struct *dir, const char *path, int len,
18 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);
20
21 static int common_prefix(const char **pathspec)
22 {
@@ -326,7 +326,7 @@ static int excluded_1(const char *pathname,
326
327 if (x->flags & EXC_FLAG_MUSTBEDIR) {
328 if (*dtype == DT_UNKNOWN)
329 - *dtype = get_dtype(NULL, pathname);
329 + *dtype = get_dtype(NULL, pathname, pathlen);
330 if (*dtype != DT_DIR)
331 continue;
332 }
@@ -566,14 +566,18 @@ static int in_pathspec(const char *path, int len, const struct path_simplify *si
566 return 0;
567 }
568
569 -static int get_dtype(struct dirent *de, const char *path)
569 +static int get_dtype(struct dirent *de, const char *path, int len)
570 {
571 int dtype = de ? DTYPE(de) : DT_UNKNOWN;
572 + struct cache_entry *ce;
573 struct stat st;
574
575 if (dtype != DT_UNKNOWN)
576 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))
581 return dtype;
582 if (S_ISREG(st.st_mode))
583 return DT_REG;
@@ -633,7 +637,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *base, in
637 continue;
638
639 if (dtype == DT_UNKNOWN)
636 - dtype = get_dtype(de, path);
640 + dtype = get_dtype(de, path, len);
641
642 /*
643 * Do we want to see just the ignored files?