mirror of
https://github.com/git-for-windows/git.git
synced 2026-05-31 02:17:14 -05:00
fscache: implement an FSCache-aware is_mount_point()
When FSCache is active, we can cache the reparse tag and use it directly to determine whether a path refers to an NTFS junction, without any additional, costly I/O. Note: this change only makes a difference with the next commit, which will make use of the FSCache in `git clean` (contingent on `core.fscache` set, of course). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
@@ -3006,6 +3006,8 @@ pid_t waitpid(pid_t pid, int *status, int options)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int (*win32_is_mount_point)(struct strbuf *path) = mingw_is_mount_point;
|
||||||
|
|
||||||
int mingw_is_mount_point(struct strbuf *path)
|
int mingw_is_mount_point(struct strbuf *path)
|
||||||
{
|
{
|
||||||
WIN32_FIND_DATAW findbuf = { 0 };
|
WIN32_FIND_DATAW findbuf = { 0 };
|
||||||
|
|||||||
@@ -481,7 +481,8 @@ static inline void convert_slashes(char *path)
|
|||||||
}
|
}
|
||||||
struct strbuf;
|
struct strbuf;
|
||||||
int mingw_is_mount_point(struct strbuf *path);
|
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 CAN_UNLINK_MOUNT_POINTS 1
|
||||||
#define PATH_SEP ';'
|
#define PATH_SEP ';'
|
||||||
char *mingw_query_user_email(void);
|
char *mingw_query_user_email(void);
|
||||||
|
|||||||
@@ -469,6 +469,7 @@ int fscache_enable(size_t initial_size)
|
|||||||
/* redirect opendir and lstat to the fscache implementations */
|
/* redirect opendir and lstat to the fscache implementations */
|
||||||
opendir = fscache_opendir;
|
opendir = fscache_opendir;
|
||||||
lstat = fscache_lstat;
|
lstat = fscache_lstat;
|
||||||
|
win32_is_mount_point = fscache_is_mount_point;
|
||||||
}
|
}
|
||||||
initialized++;
|
initialized++;
|
||||||
LeaveCriticalSection(&fscache_cs);
|
LeaveCriticalSection(&fscache_cs);
|
||||||
@@ -529,6 +530,7 @@ void fscache_disable(void)
|
|||||||
/* reset opendir and lstat to the original implementations */
|
/* reset opendir and lstat to the original implementations */
|
||||||
opendir = dirent_opendir;
|
opendir = dirent_opendir;
|
||||||
lstat = mingw_lstat;
|
lstat = mingw_lstat;
|
||||||
|
win32_is_mount_point = mingw_is_mount_point;
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&fscache_cs);
|
LeaveCriticalSection(&fscache_cs);
|
||||||
|
|
||||||
@@ -599,6 +601,39 @@ int fscache_lstat(const char *filename, struct stat *st)
|
|||||||
return 0;
|
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 {
|
typedef struct fscache_DIR {
|
||||||
struct DIR base_dir; /* extend base struct DIR */
|
struct DIR base_dir; /* extend base struct DIR */
|
||||||
struct fsentry *pfsentry;
|
struct fsentry *pfsentry;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ void fscache_flush(void);
|
|||||||
|
|
||||||
DIR *fscache_opendir(const char *dir);
|
DIR *fscache_opendir(const char *dir);
|
||||||
int fscache_lstat(const char *file_name, struct stat *buf);
|
int fscache_lstat(const char *file_name, struct stat *buf);
|
||||||
|
int fscache_is_mount_point(struct strbuf *path);
|
||||||
|
|
||||||
/* opaque fscache structure */
|
/* opaque fscache structure */
|
||||||
struct fscache;
|
struct fscache;
|
||||||
|
|||||||
Reference in New Issue
Block a user