@@ -44,6 +44,7 @@ static struct trace_key trace_fscache = TRACE_KEY_INIT(FSCACHE);
44
44
struct fsentry {
45
45
struct hashmap_entry ent ;
46
46
mode_t st_mode ;
47
+ ULONG reparse_tag ;
47
48
/* Pointer to the directory listing, or NULL for the listing itself. */
48
49
struct fsentry * list ;
49
50
/* Pointer to the next file entry of the list. */
@@ -195,6 +196,10 @@ static struct fsentry *fseentry_create_entry(struct fscache *cache,
195
196
196
197
fse = fsentry_alloc (cache , list , buf , len );
197
198
199
+ fse -> reparse_tag =
200
+ fdata -> FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ?
201
+ fdata -> EaSize : 0 ;
202
+
198
203
fse -> st_mode = file_attr_to_st_mode (fdata -> FileAttributes );
199
204
fse -> dirent .d_type = S_ISDIR (fse -> st_mode ) ? DT_DIR : DT_REG ;
200
205
fse -> u .s .st_size = fdata -> EndOfFile .LowPart |
@@ -462,6 +467,7 @@ int fscache_enable(size_t initial_size)
462
467
/* redirect opendir and lstat to the fscache implementations */
463
468
opendir = fscache_opendir ;
464
469
lstat = fscache_lstat ;
470
+ win32_is_mount_point = fscache_is_mount_point ;
465
471
}
466
472
initialized ++ ;
467
473
LeaveCriticalSection (& fscache_cs );
@@ -522,6 +528,7 @@ void fscache_disable(void)
522
528
/* reset opendir and lstat to the original implementations */
523
529
opendir = dirent_opendir ;
524
530
lstat = mingw_lstat ;
531
+ win32_is_mount_point = mingw_is_mount_point ;
525
532
}
526
533
LeaveCriticalSection (& fscache_cs );
527
534
@@ -592,6 +599,39 @@ int fscache_lstat(const char *filename, struct stat *st)
592
599
return 0 ;
593
600
}
594
601
602
+ /*
603
+ * is_mount_point() replacement, uses cache if enabled, otherwise falls
604
+ * back to mingw_is_mount_point().
605
+ */
606
+ int fscache_is_mount_point (struct strbuf * path )
607
+ {
608
+ int dirlen , base , len ;
609
+ struct heap_fsentry key [2 ];
610
+ struct fsentry * fse ;
611
+ struct fscache * cache = fscache_getcache ();
612
+
613
+ if (!cache || !do_fscache_enabled (cache , path -> buf ))
614
+ return mingw_is_mount_point (path );
615
+
616
+ cache -> lstat_requests ++ ;
617
+ /* split path into path + name */
618
+ len = path -> len ;
619
+ if (len && is_dir_sep (path -> buf [len - 1 ]))
620
+ len -- ;
621
+ base = len ;
622
+ while (base && !is_dir_sep (path -> buf [base - 1 ]))
623
+ base -- ;
624
+ dirlen = base ? base - 1 : 0 ;
625
+
626
+ /* lookup entry for path + name in cache */
627
+ fsentry_init (& key [0 ].u .ent , NULL , path -> buf , dirlen );
628
+ fsentry_init (& key [1 ].u .ent , & key [0 ].u .ent , path -> buf + base , len - base );
629
+ fse = fscache_get (cache , & key [1 ].u .ent );
630
+ if (!fse )
631
+ return mingw_is_mount_point (path );
632
+ return fse -> reparse_tag == IO_REPARSE_TAG_MOUNT_POINT ;
633
+ }
634
+
595
635
typedef struct fscache_DIR {
596
636
struct DIR base_dir ; /* extend base struct DIR */
597
637
struct fsentry * pfsentry ;
0 commit comments