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

Reply via email to