Merge branch 'kb/lstat-cache'

* kb/lstat-cache:
  lstat_cache(): introduce clear_lstat_cache() function
  lstat_cache(): introduce invalidate_lstat_cache() function
  lstat_cache(): introduce has_dirs_only_path() function
  lstat_cache(): introduce has_symlink_or_noent_leading_path() function
  lstat_cache(): more cache effective symlink/directory detection
This commit is contained in:
Junio C Hamano
2009-01-25 17:13:34 -08:00
4 changed files with 248 additions and 77 deletions

34
entry.c
View File

@ -9,35 +9,25 @@ static void create_directories(const char *path, const struct checkout *state)
const char *slash = path;
while ((slash = strchr(slash+1, '/')) != NULL) {
struct stat st;
int stat_status;
len = slash - path;
memcpy(buf, path, len);
buf[len] = 0;
if (len <= state->base_dir_len)
/*
* checkout-index --prefix=<dir>; <dir> is
* allowed to be a symlink to an existing
* directory.
*/
stat_status = stat(buf, &st);
else
/*
* if there currently is a symlink, we would
* want to replace it with a real directory.
*/
stat_status = lstat(buf, &st);
if (!stat_status && S_ISDIR(st.st_mode))
/*
* For 'checkout-index --prefix=<dir>', <dir> is
* allowed to be a symlink to an existing directory,
* and we set 'state->base_dir_len' below, such that
* we test the path components of the prefix with the
* stat() function instead of the lstat() function.
*/
if (has_dirs_only_path(len, buf, state->base_dir_len))
continue; /* ok, it is already a directory. */
/*
* We know stat_status == 0 means something exists
* there and this mkdir would fail, but that is an
* error codepath; we do not care, as we unlink and
* mkdir again in such a case.
* If this mkdir() would fail, it could be that there
* is already a symlink or something else exists
* there, therefore we then try to unlink it and try
* one more time to create the directory.
*/
if (mkdir(buf, 0777)) {
if (errno == EEXIST && state->force &&