Skip to content

Commit 78481be

Browse files
committed
Merge branch 'dont-clean-junctions-fscache'
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 <[email protected]>
2 parents 9d088d3 + dc7a164 commit 78481be

File tree

5 files changed

+47
-1
lines changed

5 files changed

+47
-1
lines changed

builtin/clean.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
10381038

10391039
if (read_cache() < 0)
10401040
die(_("index file corrupt"));
1041+
enable_fscache(active_nr);
10411042

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

1116+
disable_fscache();
11151117
strbuf_release(&abs_path);
11161118
strbuf_release(&buf);
11171119
string_list_clear(&del_list, 0);

compat/mingw.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2693,6 +2693,8 @@ pid_t waitpid(pid_t pid, int *status, int options)
26932693
return -1;
26942694
}
26952695

2696+
int (*win32_is_mount_point)(struct strbuf *path) = mingw_is_mount_point;
2697+
26962698
int mingw_is_mount_point(struct strbuf *path)
26972699
{
26982700
WIN32_FIND_DATAW findbuf = { 0 };

compat/mingw.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,8 @@ static inline void convert_slashes(char *path)
465465
}
466466
struct strbuf;
467467
int mingw_is_mount_point(struct strbuf *path);
468-
#define is_mount_point mingw_is_mount_point
468+
extern int (*win32_is_mount_point)(struct strbuf *path);
469+
#define is_mount_point win32_is_mount_point
469470
#define CAN_UNLINK_MOUNT_POINTS 1
470471
#define PATH_SEP ';'
471472
char *mingw_query_user_email(void);

compat/win32/fscache.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ static struct trace_key trace_fscache = TRACE_KEY_INIT(FSCACHE);
4343
struct fsentry {
4444
struct hashmap_entry ent;
4545
mode_t st_mode;
46+
ULONG reparse_tag;
4647
/* Pointer to the directory listing, or NULL for the listing itself. */
4748
struct fsentry *list;
4849
/* Pointer to the next file entry of the list. */
@@ -194,6 +195,10 @@ static struct fsentry *fseentry_create_entry(struct fscache *cache,
194195

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

198+
fse->reparse_tag =
199+
fdata->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ?
200+
fdata->EaSize : 0;
201+
197202
fse->st_mode = file_attr_to_st_mode(fdata->FileAttributes);
198203
fse->dirent.d_type = S_ISDIR(fse->st_mode) ? DT_DIR : DT_REG;
199204
fse->u.s.st_size = fdata->EndOfFile.LowPart |
@@ -461,6 +466,7 @@ int fscache_enable(size_t initial_size)
461466
/* redirect opendir and lstat to the fscache implementations */
462467
opendir = fscache_opendir;
463468
lstat = fscache_lstat;
469+
win32_is_mount_point = fscache_is_mount_point;
464470
}
465471
initialized++;
466472
LeaveCriticalSection(&fscache_cs);
@@ -521,6 +527,7 @@ void fscache_disable(void)
521527
/* reset opendir and lstat to the original implementations */
522528
opendir = dirent_opendir;
523529
lstat = mingw_lstat;
530+
win32_is_mount_point = mingw_is_mount_point;
524531
}
525532
LeaveCriticalSection(&fscache_cs);
526533

@@ -591,6 +598,39 @@ int fscache_lstat(const char *filename, struct stat *st)
591598
return 0;
592599
}
593600

601+
/*
602+
* is_mount_point() replacement, uses cache if enabled, otherwise falls
603+
* back to mingw_is_mount_point().
604+
*/
605+
int fscache_is_mount_point(struct strbuf *path)
606+
{
607+
int dirlen, base, len;
608+
struct heap_fsentry key[2];
609+
struct fsentry *fse;
610+
struct fscache *cache = fscache_getcache();
611+
612+
if (!cache || !do_fscache_enabled(cache, path->buf))
613+
return mingw_is_mount_point(path);
614+
615+
cache->lstat_requests++;
616+
/* split path into path + name */
617+
len = path->len;
618+
if (len && is_dir_sep(path->buf[len - 1]))
619+
len--;
620+
base = len;
621+
while (base && !is_dir_sep(path->buf[base - 1]))
622+
base--;
623+
dirlen = base ? base - 1 : 0;
624+
625+
/* lookup entry for path + name in cache */
626+
fsentry_init(&key[0].u.ent, NULL, path->buf, dirlen);
627+
fsentry_init(&key[1].u.ent, &key[0].u.ent, path->buf + base, len - base);
628+
fse = fscache_get(cache, &key[1].u.ent);
629+
if (!fse)
630+
return mingw_is_mount_point(path);
631+
return fse->reparse_tag == IO_REPARSE_TAG_MOUNT_POINT;
632+
}
633+
594634
typedef struct fscache_DIR {
595635
struct DIR base_dir; /* extend base struct DIR */
596636
struct fsentry *pfsentry;

compat/win32/fscache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ void fscache_flush(void);
2222

2323
DIR *fscache_opendir(const char *dir);
2424
int fscache_lstat(const char *file_name, struct stat *buf);
25+
int fscache_is_mount_point(struct strbuf *path);
2526

2627
/* opaque fscache structure */
2728
struct fscache;

0 commit comments

Comments
 (0)