[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