[PATCH 09/11] mount.cc: Implement poor-man's cache

Corinna Vinschen corinna-cygwin@cygwin.com
Mon Jan 18 11:51:03 GMT 2021


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


More information about the Cygwin-patches mailing list