Skip to content

Commit

Permalink
Merge branch 'dont-clean-junctions-fscache'
Browse files Browse the repository at this point in the history
We already avoid traversing NTFS junction points in `git clean -dfx`.
With this topic branch, we do that when the FSCache is enabled, too.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
  • Loading branch information
dscho committed Sep 24, 2024
2 parents 6a38ccd + cbc3820 commit 8aeffb9
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 1 deletion.
2 changes: 2 additions & 0 deletions builtin/clean.c
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)

if (repo_read_index(the_repository) < 0)
die(_("index file corrupt"));
enable_fscache(the_repository->index->cache_nr);

pl = add_pattern_list(&dir, EXC_CMDL, "--exclude option");
for (i = 0; i < exclude_list.nr; i++)
Expand Down Expand Up @@ -1112,6 +1113,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
}
}

disable_fscache();
strbuf_release(&abs_path);
strbuf_release(&buf);
string_list_clear(&del_list, 0);
Expand Down
2 changes: 2 additions & 0 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -2778,6 +2778,8 @@ pid_t waitpid(pid_t pid, int *status, int options)
return -1;
}

int (*win32_is_mount_point)(struct strbuf *path) = mingw_is_mount_point;

int mingw_is_mount_point(struct strbuf *path)
{
WIN32_FIND_DATAW findbuf = { 0 };
Expand Down
3 changes: 2 additions & 1 deletion compat/mingw.h
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,8 @@ static inline void convert_slashes(char *path)
}
struct strbuf;
int mingw_is_mount_point(struct strbuf *path);
#define is_mount_point mingw_is_mount_point
extern int (*win32_is_mount_point)(struct strbuf *path);
#define is_mount_point win32_is_mount_point
#define CAN_UNLINK_MOUNT_POINTS 1
#define PATH_SEP ';'
char *mingw_query_user_email(void);
Expand Down
40 changes: 40 additions & 0 deletions compat/win32/fscache.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ static struct trace_key trace_fscache = TRACE_KEY_INIT(FSCACHE);
struct fsentry {
struct hashmap_entry ent;
mode_t st_mode;
ULONG reparse_tag;
/* Pointer to the directory listing, or NULL for the listing itself. */
struct fsentry *list;
/* Pointer to the next file entry of the list. */
Expand Down Expand Up @@ -197,6 +198,10 @@ static struct fsentry *fseentry_create_entry(struct fscache *cache,

fse = fsentry_alloc(cache, list, buf, len);

fse->reparse_tag =
fdata->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ?
fdata->EaSize : 0;

fse->st_mode = file_attr_to_st_mode(fdata->FileAttributes);
fse->dirent.d_type = S_ISDIR(fse->st_mode) ? DT_DIR : DT_REG;
fse->u.s.st_size = fdata->EndOfFile.LowPart |
Expand Down Expand Up @@ -464,6 +469,7 @@ int fscache_enable(size_t initial_size)
/* redirect opendir and lstat to the fscache implementations */
opendir = fscache_opendir;
lstat = fscache_lstat;
win32_is_mount_point = fscache_is_mount_point;
}
initialized++;
LeaveCriticalSection(&fscache_cs);
Expand Down Expand Up @@ -524,6 +530,7 @@ void fscache_disable(void)
/* reset opendir and lstat to the original implementations */
opendir = dirent_opendir;
lstat = mingw_lstat;
win32_is_mount_point = mingw_is_mount_point;
}
LeaveCriticalSection(&fscache_cs);

Expand Down Expand Up @@ -594,6 +601,39 @@ int fscache_lstat(const char *filename, struct stat *st)
return 0;
}

/*
* is_mount_point() replacement, uses cache if enabled, otherwise falls
* back to mingw_is_mount_point().
*/
int fscache_is_mount_point(struct strbuf *path)
{
int dirlen, base, len;
struct heap_fsentry key[2];
struct fsentry *fse;
struct fscache *cache = fscache_getcache();

if (!cache || !do_fscache_enabled(cache, path->buf))
return mingw_is_mount_point(path);

cache->lstat_requests++;
/* split path into path + name */
len = path->len;
if (len && is_dir_sep(path->buf[len - 1]))
len--;
base = len;
while (base && !is_dir_sep(path->buf[base - 1]))
base--;
dirlen = base ? base - 1 : 0;

/* lookup entry for path + name in cache */
fsentry_init(&key[0].u.ent, NULL, path->buf, dirlen);
fsentry_init(&key[1].u.ent, &key[0].u.ent, path->buf + base, len - base);
fse = fscache_get(cache, &key[1].u.ent);
if (!fse)
return mingw_is_mount_point(path);
return fse->reparse_tag == IO_REPARSE_TAG_MOUNT_POINT;
}

typedef struct fscache_DIR {
struct DIR base_dir; /* extend base struct DIR */
struct fsentry *pfsentry;
Expand Down
1 change: 1 addition & 0 deletions compat/win32/fscache.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ void fscache_flush(void);

DIR *fscache_opendir(const char *dir);
int fscache_lstat(const char *file_name, struct stat *buf);
int fscache_is_mount_point(struct strbuf *path);

/* opaque fscache structure */
struct fscache;
Expand Down

0 comments on commit 8aeffb9

Please sign in to comment.