diff options
Diffstat (limited to 'symlinks.c')
-rw-r--r-- | symlinks.c | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/symlinks.c b/symlinks.c index ae57e5603b..4596aee9dc 100644 --- a/symlinks.c +++ b/symlinks.c @@ -1,38 +1,30 @@ #include "cache.h" -static struct cache_def { - char path[PATH_MAX + 1]; - int len; - int flags; - int track_flags; - int prefix_len_stat_func; -} cache; - /* * Returns the length (on a path component basis) of the longest - * common prefix match of 'name' and the cached path string. + * common prefix match of 'name_a' and 'name_b'. */ -static inline int longest_match_lstat_cache(int len, const char *name, - int *previous_slash) +static int longest_path_match(const char *name_a, int len_a, + const char *name_b, int len_b, + int *previous_slash) { int max_len, match_len = 0, match_len_prev = 0, i = 0; - max_len = len < cache.len ? len : cache.len; - while (i < max_len && name[i] == cache.path[i]) { - if (name[i] == '/') { + max_len = len_a < len_b ? len_a : len_b; + while (i < max_len && name_a[i] == name_b[i]) { + if (name_a[i] == '/') { match_len_prev = match_len; match_len = i; } i++; } /* - * Is the cached path string a substring of 'name', is 'name' - * a substring of the cached path string, or is 'name' and the - * cached path string the exact same string? + * Is 'name_b' a substring of 'name_a', the other way around, + * or is 'name_a' and 'name_b' the exact same string? */ - if (i >= max_len && ((len > cache.len && name[cache.len] == '/') || - (len < cache.len && cache.path[len] == '/') || - (len == cache.len))) { + if (i >= max_len && ((len_a > len_b && name_a[len_b] == '/') || + (len_a < len_b && name_b[len_a] == '/') || + (len_a == len_b))) { match_len_prev = match_len; match_len = i; } @@ -40,6 +32,14 @@ static inline int longest_match_lstat_cache(int len, const char *name, return match_len; } +static struct cache_def { + char path[PATH_MAX + 1]; + int len; + int flags; + int track_flags; + int prefix_len_stat_func; +} cache; + static inline void reset_lstat_cache(void) { cache.path[0] = '\0'; @@ -94,7 +94,8 @@ static int lstat_cache(int len, const char *name, * the 2 "excluding" path types. */ match_len = last_slash = - longest_match_lstat_cache(len, name, &previous_slash); + longest_path_match(name, len, cache.path, cache.len, + &previous_slash); match_flags = cache.flags & track_flags & (FL_NOENT|FL_SYMLINK); if (match_flags && match_len == cache.len) return match_flags; @@ -188,7 +189,8 @@ void invalidate_lstat_cache(int len, const char *name) { int match_len, previous_slash; - match_len = longest_match_lstat_cache(len, name, &previous_slash); + match_len = longest_path_match(name, len, cache.path, cache.len, + &previous_slash); if (len == match_len) { if ((cache.track_flags & FL_DIR) && previous_slash > 0) { cache.path[previous_slash] = '\0'; |