On Jan 15 14:45, Ben Wijen wrote: > Try to avoid NtQueryVolumeInformationFile. > --- > winsup/cygwin/mount.cc | 78 ++++++++++++++++++++++++++++-------------- > winsup/cygwin/mount.h | 2 +- > winsup/cygwin/path.cc | 2 +- > winsup/cygwin/path.h | 1 + > 4 files changed, 56 insertions(+), 27 deletions(-) > > diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc > index e0349815d..1d2b3a61a 100644 > --- a/winsup/cygwin/mount.cc > +++ b/winsup/cygwin/mount.cc > @@ -82,6 +82,32 @@ win32_device_name (const char *src_path, char *win32_path, > device& dev) > return true; > } > > +static uint32_t > +hash_prefix (const PUNICODE_STRING upath) > +{ > + UNICODE_STRING prefix; > + WCHAR *p; > + > + if (upath->Buffer[5] == L':' && upath->Buffer[6] == L'\\') > + p = upath->Buffer + 6; > + else > + { > + /* We're expecting an UNC path. Move p to the backslash after > + "\??\UNC\server\share" or the trailing NUL. */ > + p = upath->Buffer + 7; /* Skip "\??\UNC" */ > + int bs_cnt = 0; > + > + while (*++p) > + if (*p == L'\\') > + if (++bs_cnt > 1) > + break; > + } > + RtlInitCountedUnicodeString (&prefix, upath->Buffer, > + (p - upath->Buffer) * sizeof(WCHAR)); > + > + return hash_path_name ((ino_t) 0, &prefix); > +} > +
Ok, so hash_prefix reduces the path to a drive letter or the UNC path prefix and hashes it. However, what about partitions mounted to a subdir of, say, drive C? In that case the hashing goes awry, because you're comparing with the hash of drive C while the path is actually pointing to another partition. > @@ -233,27 +281,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) > a unique per-drive/share hash. */ > if (ffvi_buf.ffvi.VolumeSerialNumber == 0) > { > - UNICODE_STRING path_prefix; > - WCHAR *p; > - > - if (upath->Buffer[5] == L':' && upath->Buffer[6] == L'\\') > - p = upath->Buffer + 6; > - else > - { > - /* We're expecting an UNC path. Move p to the backslash after > - "\??\UNC\server\share" or the trailing NUL. */ > - p = upath->Buffer + 7; /* Skip "\??\UNC" */ > - int bs_cnt = 0; > - > - while (*++p) > - if (*p == L'\\') > - if (++bs_cnt > 1) > - break; > - } > - RtlInitCountedUnicodeString (&path_prefix, upath->Buffer, > - (p - upath->Buffer) * sizeof (WCHAR)); > - ffvi_buf.ffvi.VolumeSerialNumber = hash_path_name ((ino_t) 0, > - &path_prefix); > + ffvi_buf.ffvi.VolumeSerialNumber = hash_prefix(upath); Please note that we did this *only* for border case FSes returning a VSN of 0. This was sufficient for these cases, but not in a a general sense. Corinna