@@ -46,6 +46,7 @@ static struct trace_key trace_fscache = TRACE_KEY_INIT(FSCACHE);
4646struct 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. */
@@ -197,6 +198,10 @@ static struct fsentry *fseentry_create_entry(struct fscache *cache,
197198
198199 fse = fsentry_alloc (cache , list , buf , len );
199200
201+ fse -> reparse_tag =
202+ fdata -> FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ?
203+ fdata -> EaSize : 0 ;
204+
200205 fse -> st_mode = file_attr_to_st_mode (fdata -> FileAttributes );
201206 fse -> dirent .d_type = S_ISDIR (fse -> st_mode ) ? DT_DIR : DT_REG ;
202207 fse -> u .s .st_size = fdata -> EndOfFile .LowPart |
@@ -464,6 +469,7 @@ int fscache_enable(size_t initial_size)
464469 /* redirect opendir and lstat to the fscache implementations */
465470 opendir = fscache_opendir ;
466471 lstat = fscache_lstat ;
472+ win32_is_mount_point = fscache_is_mount_point ;
467473 }
468474 initialized ++ ;
469475 LeaveCriticalSection (& fscache_cs );
@@ -524,6 +530,7 @@ void fscache_disable(void)
524530 /* reset opendir and lstat to the original implementations */
525531 opendir = dirent_opendir ;
526532 lstat = mingw_lstat ;
533+ win32_is_mount_point = mingw_is_mount_point ;
527534 }
528535 LeaveCriticalSection (& fscache_cs );
529536
@@ -594,6 +601,39 @@ int fscache_lstat(const char *filename, struct stat *st)
594601 return 0 ;
595602}
596603
604+ /*
605+ * is_mount_point() replacement, uses cache if enabled, otherwise falls
606+ * back to mingw_is_mount_point().
607+ */
608+ int fscache_is_mount_point (struct strbuf * path )
609+ {
610+ int dirlen , base , len ;
611+ struct heap_fsentry key [2 ];
612+ struct fsentry * fse ;
613+ struct fscache * cache = fscache_getcache ();
614+
615+ if (!cache || !do_fscache_enabled (cache , path -> buf ))
616+ return mingw_is_mount_point (path );
617+
618+ cache -> lstat_requests ++ ;
619+ /* split path into path + name */
620+ len = path -> len ;
621+ if (len && is_dir_sep (path -> buf [len - 1 ]))
622+ len -- ;
623+ base = len ;
624+ while (base && !is_dir_sep (path -> buf [base - 1 ]))
625+ base -- ;
626+ dirlen = base ? base - 1 : 0 ;
627+
628+ /* lookup entry for path + name in cache */
629+ fsentry_init (& key [0 ].u .ent , NULL , path -> buf , dirlen );
630+ fsentry_init (& key [1 ].u .ent , & key [0 ].u .ent , path -> buf + base , len - base );
631+ fse = fscache_get (cache , & key [1 ].u .ent );
632+ if (!fse )
633+ return mingw_is_mount_point (path );
634+ return fse -> reparse_tag == IO_REPARSE_TAG_MOUNT_POINT ;
635+ }
636+
597637typedef struct fscache_DIR {
598638 struct DIR base_dir ; /* extend base struct DIR */
599639 struct fsentry * pfsentry ;
0 commit comments