Skip to content

Commit ebd7c0d

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 0f35fe6 + 7611a8a commit ebd7c0d

File tree

5 files changed

+46
-1
lines changed

5 files changed

+46
-1
lines changed

builtin/clean.c

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

996996
if (read_cache() < 0)
997997
die(_("index file corrupt"));
998+
enable_fscache(active_nr);
998999

9991000
if (!ignored)
10001001
setup_standard_excludes(&dir);
@@ -1084,6 +1085,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
10841085
}
10851086
}
10861087

1088+
disable_fscache();
10871089
strbuf_release(&abs_path);
10881090
strbuf_release(&buf);
10891091
string_list_clear(&del_list, 0);

compat/mingw.c

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

2399+
int (*win32_is_mount_point)(struct strbuf *path) = mingw_is_mount_point;
2400+
23992401
int mingw_is_mount_point(struct strbuf *path)
24002402
{
24012403
WIN32_FIND_DATAW findbuf = { 0 };

compat/mingw.h

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

compat/win32/fscache.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ static struct trace_key trace_fscache = TRACE_KEY_INIT(FSCACHE);
4141
struct fsentry {
4242
struct hashmap_entry ent;
4343
mode_t st_mode;
44+
ULONG reparse_tag;
4445
/* Length of name. */
4546
unsigned short len;
4647
/*
@@ -180,6 +181,10 @@ static struct fsentry *fseentry_create_entry(struct fscache *cache, struct fsent
180181

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

184+
fse->reparse_tag =
185+
fdata->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ?
186+
fdata->EaSize : 0;
187+
183188
fse->st_mode = file_attr_to_st_mode(fdata->FileAttributes);
184189
fse->u.s.st_size = fdata->EndOfFile.LowPart | (((off_t)fdata->EndOfFile.HighPart) << 32);
185190
filetime_to_timespec((FILETIME *)&(fdata->LastAccessTime), &(fse->u.s.st_atim));
@@ -439,6 +444,7 @@ int fscache_enable(size_t initial_size)
439444
/* redirect opendir and lstat to the fscache implementations */
440445
opendir = fscache_opendir;
441446
lstat = fscache_lstat;
447+
win32_is_mount_point = fscache_is_mount_point;
442448
}
443449
initialized++;
444450
LeaveCriticalSection(&fscache_cs);
@@ -499,6 +505,7 @@ void fscache_disable(void)
499505
/* reset opendir and lstat to the original implementations */
500506
opendir = dirent_opendir;
501507
lstat = mingw_lstat;
508+
win32_is_mount_point = mingw_is_mount_point;
502509
}
503510
LeaveCriticalSection(&fscache_cs);
504511

@@ -566,6 +573,38 @@ int fscache_lstat(const char *filename, struct stat *st)
566573
return 0;
567574
}
568575

576+
/*
577+
* is_mount_point() replacement, uses cache if enabled, otherwise falls
578+
* back to mingw_is_mount_point().
579+
*/
580+
int fscache_is_mount_point(struct strbuf *path)
581+
{
582+
int dirlen, base, len;
583+
struct fsentry key[2], *fse;
584+
struct fscache *cache = fscache_getcache();
585+
586+
if (!cache || !do_fscache_enabled(cache, path->buf))
587+
return mingw_is_mount_point(path);
588+
589+
cache->lstat_requests++;
590+
/* split path into path + name */
591+
len = path->len;
592+
if (len && is_dir_sep(path->buf[len - 1]))
593+
len--;
594+
base = len;
595+
while (base && !is_dir_sep(path->buf[base - 1]))
596+
base--;
597+
dirlen = base ? base - 1 : 0;
598+
599+
/* lookup entry for path + name in cache */
600+
fsentry_init(key, NULL, path->buf, dirlen);
601+
fsentry_init(key + 1, key, path->buf + base, len - base);
602+
fse = fscache_get(cache, key + 1);
603+
if (!fse)
604+
return mingw_is_mount_point(path);
605+
return fse->reparse_tag == IO_REPARSE_TAG_MOUNT_POINT;
606+
}
607+
569608
typedef struct fscache_DIR {
570609
struct DIR base_dir; /* extend base struct DIR */
571610
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)