@@ -41,6 +41,7 @@ static struct trace_key trace_fscache = TRACE_KEY_INIT(FSCACHE);
41
41
struct fsentry {
42
42
struct hashmap_entry ent ;
43
43
mode_t st_mode ;
44
+ ULONG reparse_tag ;
44
45
/* Pointer to the directory listing, or NULL for the listing itself. */
45
46
struct fsentry * list ;
46
47
/* Pointer to the next file entry of the list. */
@@ -189,6 +190,10 @@ static struct fsentry *fseentry_create_entry(struct fscache *cache,
189
190
190
191
fse = fsentry_alloc (cache , list , buf , len );
191
192
193
+ fse -> reparse_tag =
194
+ fdata -> FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ?
195
+ fdata -> EaSize : 0 ;
196
+
192
197
fse -> st_mode = file_attr_to_st_mode (fdata -> FileAttributes );
193
198
fse -> dirent .d_type = S_ISDIR (fse -> st_mode ) ? DT_DIR : DT_REG ;
194
199
fse -> u .s .st_size = fdata -> EndOfFile .LowPart |
@@ -456,6 +461,7 @@ int fscache_enable(size_t initial_size)
456
461
/* redirect opendir and lstat to the fscache implementations */
457
462
opendir = fscache_opendir ;
458
463
lstat = fscache_lstat ;
464
+ win32_is_mount_point = fscache_is_mount_point ;
459
465
}
460
466
initialized ++ ;
461
467
LeaveCriticalSection (& fscache_cs );
@@ -516,6 +522,7 @@ void fscache_disable(void)
516
522
/* reset opendir and lstat to the original implementations */
517
523
opendir = dirent_opendir ;
518
524
lstat = mingw_lstat ;
525
+ win32_is_mount_point = mingw_is_mount_point ;
519
526
}
520
527
LeaveCriticalSection (& fscache_cs );
521
528
@@ -584,6 +591,39 @@ int fscache_lstat(const char *filename, struct stat *st)
584
591
return 0 ;
585
592
}
586
593
594
+ /*
595
+ * is_mount_point() replacement, uses cache if enabled, otherwise falls
596
+ * back to mingw_is_mount_point().
597
+ */
598
+ int fscache_is_mount_point (struct strbuf * path )
599
+ {
600
+ int dirlen , base , len ;
601
+ struct heap_fsentry key [2 ];
602
+ struct fsentry * fse ;
603
+ struct fscache * cache = fscache_getcache ();
604
+
605
+ if (!cache || !do_fscache_enabled (cache , path -> buf ))
606
+ return mingw_is_mount_point (path );
607
+
608
+ cache -> lstat_requests ++ ;
609
+ /* split path into path + name */
610
+ len = path -> len ;
611
+ if (len && is_dir_sep (path -> buf [len - 1 ]))
612
+ len -- ;
613
+ base = len ;
614
+ while (base && !is_dir_sep (path -> buf [base - 1 ]))
615
+ base -- ;
616
+ dirlen = base ? base - 1 : 0 ;
617
+
618
+ /* lookup entry for path + name in cache */
619
+ fsentry_init (& key [0 ].ent , NULL , path -> buf , dirlen );
620
+ fsentry_init (& key [1 ].ent , & key [0 ].ent , path -> buf + base , len - base );
621
+ fse = fscache_get (cache , & key [1 ].ent );
622
+ if (!fse )
623
+ return mingw_is_mount_point (path );
624
+ return fse -> reparse_tag == IO_REPARSE_TAG_MOUNT_POINT ;
625
+ }
626
+
587
627
typedef struct fscache_DIR {
588
628
struct DIR base_dir ; /* extend base struct DIR */
589
629
struct fsentry * pfsentry ;
0 commit comments