Skip to content

Commit 00ceb53

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 4c0ad9f + be4a4b5 commit 00ceb53

File tree

5 files changed

+52
-1
lines changed

5 files changed

+52
-1
lines changed

builtin/clean.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,7 @@ int cmd_clean(int argc,
10431043

10441044
if (repo_read_index(the_repository) < 0)
10451045
die(_("index file corrupt"));
1046+
enable_fscache(the_repository->index->cache_nr);
10461047

10471048
pl = add_pattern_list(&dir, EXC_CMDL, "--exclude option");
10481049
for (i = 0; i < exclude_list.nr; i++)
@@ -1117,6 +1118,7 @@ int cmd_clean(int argc,
11171118
}
11181119
}
11191120

1121+
disable_fscache();
11201122
strbuf_release(&abs_path);
11211123
strbuf_release(&buf);
11221124
string_list_clear(&del_list, 0);

compat/mingw.c

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

2986+
int (*win32_is_mount_point)(struct strbuf *path) = mingw_is_mount_point;
2987+
29862988
int mingw_is_mount_point(struct strbuf *path)
29872989
{
29882990
WIN32_FIND_DATAW findbuf = { 0 };

compat/mingw.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ static inline void convert_slashes(char *path)
4040
}
4141
struct strbuf;
4242
int mingw_is_mount_point(struct strbuf *path);
43-
#define is_mount_point mingw_is_mount_point
43+
extern int (*win32_is_mount_point)(struct strbuf *path);
44+
#define is_mount_point win32_is_mount_point
4445
#define CAN_UNLINK_MOUNT_POINTS 1
4546
#define PATH_SEP ';'
4647
char *mingw_query_user_email(void);

compat/win32/fscache.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static struct trace_key trace_fscache = TRACE_KEY_INIT(FSCACHE);
4646
struct fsentry {
4747
struct hashmap_entry ent;
4848
mode_t st_mode;
49+
ULONG reparse_tag;
4950
/* Pointer to the directory listing, or NULL for the listing itself. */
5051
struct fsentry *list;
5152
/* Pointer to the next file entry of the list. */
@@ -202,6 +203,10 @@ static struct fsentry *fseentry_create_entry(struct fscache *cache,
202203

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

206+
fse->reparse_tag =
207+
fdata->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ?
208+
fdata->EaSize : 0;
209+
205210
fse->st_mode = file_attr_to_st_mode(fdata->FileAttributes);
206211
fse->dirent.d_type = S_ISDIR(fse->st_mode) ? DT_DIR : DT_REG;
207212
fse->u.s.st_size = fdata->EndOfFile.LowPart |
@@ -469,6 +474,7 @@ int fscache_enable(size_t initial_size)
469474
/* redirect opendir and lstat to the fscache implementations */
470475
opendir = fscache_opendir;
471476
lstat = fscache_lstat;
477+
win32_is_mount_point = fscache_is_mount_point;
472478
}
473479
initialized++;
474480
LeaveCriticalSection(&fscache_cs);
@@ -529,6 +535,7 @@ void fscache_disable(void)
529535
/* reset opendir and lstat to the original implementations */
530536
opendir = dirent_opendir;
531537
lstat = mingw_lstat;
538+
win32_is_mount_point = mingw_is_mount_point;
532539
}
533540
LeaveCriticalSection(&fscache_cs);
534541

@@ -604,6 +611,44 @@ int fscache_lstat(const char *filename, struct stat *st)
604611
return 0;
605612
}
606613

614+
/*
615+
* is_mount_point() replacement, uses cache if enabled, otherwise falls
616+
* back to mingw_is_mount_point().
617+
*/
618+
int fscache_is_mount_point(struct strbuf *path)
619+
{
620+
int dirlen, base, len;
621+
#pragma GCC diagnostic push
622+
#ifdef __clang__
623+
#pragma GCC diagnostic ignored "-Wflexible-array-extensions"
624+
#endif
625+
struct heap_fsentry key[2];
626+
#pragma GCC diagnostic pop
627+
struct fsentry *fse;
628+
struct fscache *cache = fscache_getcache();
629+
630+
if (!cache || !do_fscache_enabled(cache, path->buf))
631+
return mingw_is_mount_point(path);
632+
633+
cache->lstat_requests++;
634+
/* split path into path + name */
635+
len = path->len;
636+
if (len && is_dir_sep(path->buf[len - 1]))
637+
len--;
638+
base = len;
639+
while (base && !is_dir_sep(path->buf[base - 1]))
640+
base--;
641+
dirlen = base ? base - 1 : 0;
642+
643+
/* lookup entry for path + name in cache */
644+
fsentry_init(&key[0].u.ent, NULL, path->buf, dirlen);
645+
fsentry_init(&key[1].u.ent, &key[0].u.ent, path->buf + base, len - base);
646+
fse = fscache_get(cache, &key[1].u.ent);
647+
if (!fse)
648+
return mingw_is_mount_point(path);
649+
return fse->reparse_tag == IO_REPARSE_TAG_MOUNT_POINT;
650+
}
651+
607652
typedef struct fscache_DIR {
608653
struct DIR base_dir; /* extend base struct DIR */
609654
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)