On Tue, 7 Jul 2009, Dmitry Potapov wrote: > > It appears that the second 'stat' for files on Windows caused by lack > of d_type in dirent. When I recompiled the Linux version with > NO_D_TYPE_IN_DIRENT = YesPlease, I got the same result for files. > (Still I am not sure what caused those extra stat calls for > directory, maybe, it is Cygwin specific...) > > The question is whether it is possible to avoid this redundant 'stat' > for files on system that do not have d_type in dirent or that would > require too much modification? Is it possible to use the cache where > d_stat is not available provided that the entry is marked as uptodate? Hmm. Sure. Something like this? Linus --- dir.c | 14 +++++++++----- 1 files changed, 9 insertions(+), 5 deletions(-) diff --git a/dir.c b/dir.c index 74b3bbf..aaf269b 100644 --- a/dir.c +++ b/dir.c @@ -17,7 +17,7 @@ struct path_simplify { static int read_directory_recursive(struct dir_struct *dir, const char *path, const char *base, int baselen, 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 pathlen); int common_prefix(const char **pathspec) { @@ -307,7 +307,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; } @@ -547,14 +547,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 pathlen) { 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, pathlen, 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; @@ -613,7 +617,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co continue; if (dtype == DT_UNKNOWN) - dtype = get_dtype(de, fullname); + dtype = get_dtype(de, fullname, baselen + len); /* * Do we want to see just the ignored files? -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html