@@ -46,6 +46,7 @@ static struct trace_key trace_fscache = TRACE_KEY_INIT(FSCACHE);
46
46
struct fsentry {
47
47
struct hashmap_entry ent ;
48
48
mode_t st_mode ;
49
+ ULONG reparse_tag ;
49
50
/* Pointer to the directory listing, or NULL for the listing itself. */
50
51
struct fsentry * list ;
51
52
/* Pointer to the next file entry of the list. */
@@ -202,6 +203,10 @@ static struct fsentry *fseentry_create_entry(struct fscache *cache,
202
203
203
204
fse = fsentry_alloc (cache , list , buf , len );
204
205
206
+ fse -> reparse_tag =
207
+ fdata -> FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ?
208
+ fdata -> EaSize : 0 ;
209
+
205
210
fse -> st_mode = file_attr_to_st_mode (fdata -> FileAttributes );
206
211
fse -> dirent .d_type = S_ISDIR (fse -> st_mode ) ? DT_DIR : DT_REG ;
207
212
fse -> u .s .st_size = fdata -> EndOfFile .LowPart |
@@ -469,6 +474,7 @@ int fscache_enable(size_t initial_size)
469
474
/* redirect opendir and lstat to the fscache implementations */
470
475
opendir = fscache_opendir ;
471
476
lstat = fscache_lstat ;
477
+ win32_is_mount_point = fscache_is_mount_point ;
472
478
}
473
479
initialized ++ ;
474
480
LeaveCriticalSection (& fscache_cs );
@@ -529,6 +535,7 @@ void fscache_disable(void)
529
535
/* reset opendir and lstat to the original implementations */
530
536
opendir = dirent_opendir ;
531
537
lstat = mingw_lstat ;
538
+ win32_is_mount_point = mingw_is_mount_point ;
532
539
}
533
540
LeaveCriticalSection (& fscache_cs );
534
541
@@ -604,6 +611,44 @@ int fscache_lstat(const char *filename, struct stat *st)
604
611
return 0 ;
605
612
}
606
613
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
+
607
652
typedef struct fscache_DIR {
608
653
struct DIR base_dir ; /* extend base struct DIR */
609
654
struct fsentry * pfsentry ;
0 commit comments