public inbox for cygwin-patches@cygwin.com
 help / color / mirror / Atom feed
From: Ben Wijen <ben@wijen.net>
To: cygwin-patches@cygwin.com
Subject: [PATCH 09/11] mount.cc: Implement poor-man's cache
Date: Fri, 15 Jan 2021 14:45:32 +0100	[thread overview]
Message-ID: <20210115134534.13290-10-ben@wijen.net> (raw)
In-Reply-To: <20210115134534.13290-1-ben@wijen.net>

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);
+}
+
 /* Beginning with Samba 3.0.28a, Samba allows to get version information using
    the ExtendedInfo member returned by a FileFsObjectIdInformation request.
    We just store the samba_version information for now.  Older versions than
@@ -106,14 +132,16 @@ class fs_info_cache
   struct {
     fs_info fsi;
     uint32_t hash;
+    uint32_t prefix_hash;
   } entry[MAX_FS_INFO_CNT];
 
   uint32_t genhash (PFILE_FS_VOLUME_INFORMATION);
 
 public:
   fs_info_cache () : count (0) { fsi_lock.init ("fsi_lock"); }
+  fs_info *search (uint32_t);
   fs_info *search (PFILE_FS_VOLUME_INFORMATION, uint32_t &);
-  void add (uint32_t, fs_info *);
+  void add (uint32_t, fs_info *, uint32_t);
 };
 
 static fs_info_cache fsi_cache;
@@ -142,22 +170,31 @@ fs_info_cache::search (PFILE_FS_VOLUME_INFORMATION pffvi, uint32_t &hash)
       return &entry[i].fsi;
   return NULL;
 }
+fs_info*
+fs_info_cache::search (uint32_t prefix_hash)
+{
+  for (uint32_t i = 0; i < count; ++i)
+    if (entry[i].prefix_hash == prefix_hash)
+      return &entry[i].fsi;
+  return NULL;
+}
 
 void
-fs_info_cache::add (uint32_t hashval, fs_info *new_fsi)
+fs_info_cache::add (uint32_t hashval, fs_info *new_fsi, uint32_t prefix_hash)
 {
   fsi_lock.acquire ();
   if (count < MAX_FS_INFO_CNT)
     {
       entry[count].fsi = *new_fsi;
       entry[count].hash = hashval;
+      entry[count].prefix_hash = prefix_hash;
       ++count;
     }
   fsi_lock.release ();
 }
 
 bool
-fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
+fs_info::update (PUNICODE_STRING upath, HANDLE in_vol, bool use_prefix_hash)
 {
   NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;
   HANDLE vol;
@@ -178,6 +215,17 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
   UNICODE_STRING fsname;
 
   clear ();
+
+  if (use_prefix_hash)
+    {
+      fs_info *fsi = fsi_cache.search (hash_prefix (upath));
+      if (fsi)
+        {
+          *this = *fsi;
+          return true;
+        }
+    }
+
   /* Always caseinsensitive.  We really just need access to the drive. */
   InitializeObjectAttributes (&attr, upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
   if (in_vol)
@@ -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);
 	}
       fs_info *fsi = fsi_cache.search (&ffvi_buf.ffvi, hash);
       if (fsi)
@@ -460,7 +488,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
 
   if (!in_vol)
     NtClose (vol);
-  fsi_cache.add (hash, this);
+  fsi_cache.add (hash, this, hash_prefix (upath));
   return true;
 }
 
diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h
index 122a679a8..86b72fb4c 100644
--- a/winsup/cygwin/mount.h
+++ b/winsup/cygwin/mount.h
@@ -124,7 +124,7 @@ class fs_info
 
   const char *fsname () const { return fsn[0] ? fsn : "unknown"; }
 
-  bool __reg3 update (PUNICODE_STRING, HANDLE);
+  bool __reg3 update (PUNICODE_STRING, HANDLE, bool=false);
   bool inited () const { return !!status.flags; }
 };
 
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index f00707e86..9e803f986 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -1179,7 +1179,7 @@ path_conv::check (const char *src, unsigned opt,
 	{
 	  /* If FS hasn't been checked already in symlink_info::check,
 	     do so now. */
-	  if (fs.inited ()|| fs.update (get_nt_native_path (), NULL))
+	  if (fs.inited ()|| fs.update (get_nt_native_path (), NULL, opt & PC_FS_USE_PREFIX_HASH))
 	    {
 	      /* Incoming DOS paths are treated like DOS paths in native
 		 Windows applications.  No ACLs, just default settings. */
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index 56855e1c9..b9264811e 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -60,6 +60,7 @@ enum pathconv_arg
   PC_NO_ACCESS_CHECK	 = _BIT (13),	/* helper flag for error check */
   PC_SYM_NOFOLLOW_DIR	 = _BIT (14),	/* don't follow a trailing slash */
   PC_SKIP_SYM_CHECK	 = _BIT (15),	/* skip symlink_info::check */
+  PC_FS_USE_PREFIX_HASH	 = _BIT (16),	/* in fs_info search by prefix hash */
   PC_DONT_USE		 = _BIT (31)	/* conversion to signed happens. */
 };
 
-- 
2.29.2


  parent reply	other threads:[~2021-01-15 13:46 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-15 13:45 [PATCH 00/11] Improve rm speed Ben Wijen
2021-01-15 13:45 ` [PATCH 01/11] syscalls.cc: unlink_nt: Try FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE first Ben Wijen
2021-01-18 10:25   ` Corinna Vinschen
2021-01-18 10:45   ` Corinna Vinschen
2021-01-18 12:11     ` Ben
2021-01-18 12:22       ` Corinna Vinschen
2021-01-18 14:30         ` Ben
2021-01-18 14:39           ` Corinna Vinschen
2021-01-18 14:59             ` Ben
2021-01-15 13:45 ` [PATCH 02/11] syscalls.cc: Deduplicate _remove_r Ben Wijen
2021-01-18 10:56   ` Corinna Vinschen
2021-01-18 12:40     ` Ben
2021-01-18 13:04       ` Corinna Vinschen
2021-01-18 13:51         ` Ben
2021-01-18 14:49           ` Corinna Vinschen
2021-01-18 14:58             ` Ben
2021-01-15 13:45 ` [PATCH 03/11] syscalls.cc: Fix num_links Ben Wijen
2021-01-18 11:01   ` Corinna Vinschen
2021-01-15 13:45 ` [PATCH 04/11] syscalls.cc: Use EISDIR Ben Wijen
2021-01-18 11:06   ` Corinna Vinschen
2021-01-15 13:45 ` [PATCH 05/11] Cygwin: Move post-dir unlink check Ben Wijen
2021-01-18 11:08   ` Corinna Vinschen
2021-01-18 14:31     ` Ben
2021-01-18 14:52       ` Corinna Vinschen
2021-01-15 13:45 ` [PATCH 06/11] cxx.cc: Fix dynamic initialization for static local variables Ben Wijen
2021-01-18 11:33   ` Corinna Vinschen
2021-01-15 13:45 ` [PATCH 07/11] syscalls.cc: Implement non-path_conv dependent _unlink_nt Ben Wijen
2021-01-18 10:51   ` Ben
2021-01-15 13:45 ` [PATCH 08/11] path.cc: Allow to skip filesystem checks Ben Wijen
2021-01-18 11:36   ` Corinna Vinschen
2021-01-18 17:15     ` Ben
2021-01-19  9:25       ` Corinna Vinschen
2021-01-15 13:45 ` Ben Wijen [this message]
2021-01-18 11:51   ` [PATCH 09/11] mount.cc: Implement poor-man's cache Corinna Vinschen
2021-02-03 11:38     ` Ben
2021-02-04 19:37       ` Corinna Vinschen
2021-01-15 13:45 ` [PATCH 10/11] syscalls.cc: Expose shallow-pathconv unlink_nt Ben Wijen
2021-01-15 13:45 ` [PATCH 11/11] dir.cc: Try unlink_nt first Ben Wijen
2021-01-18 12:13   ` Corinna Vinschen
2021-01-18 17:07     ` Ben
2021-01-18 17:18       ` Ben
2021-01-19  9:54       ` Corinna Vinschen
2021-01-20 16:10 ` [PATCH v2 0/8] Improve rm speed Ben Wijen
2021-01-20 16:10 ` [PATCH v2 1/8] syscalls.cc: unlink_nt: Try FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE Ben Wijen
2021-01-22 10:52   ` Corinna Vinschen
2021-01-22 15:47     ` [PATCH v3 " Ben Wijen
2021-01-25 10:30       ` Corinna Vinschen
2021-01-20 16:10 ` [PATCH v2 2/8] syscalls.cc: Deduplicate remove Ben Wijen
2021-01-22 12:22   ` Corinna Vinschen
2021-01-22 15:47     ` [PATCH v3 " Ben Wijen
2021-01-25 18:58       ` Corinna Vinschen
2021-01-20 16:10 ` [PATCH v2 3/8] Cygwin: Move post-dir unlink check Ben Wijen
2021-01-22 12:35   ` Corinna Vinschen
2021-01-20 16:10 ` [PATCH v2 4/8] syscalls.cc: Implement non-path_conv dependent _unlink_nt Ben Wijen
2021-01-26 11:34   ` Corinna Vinschen
2021-02-03 11:03     ` Ben
2021-02-04 19:29       ` Corinna Vinschen
2021-01-20 16:10 ` [PATCH v2 5/8] path.cc: Allow to skip filesystem checks Ben Wijen
2021-01-20 16:10 ` [PATCH v2 6/8] syscalls.cc: Expose shallow-pathconv unlink_nt Ben Wijen
2021-01-26 11:45   ` Corinna Vinschen
2021-01-20 16:10 ` [PATCH v2 7/8] dir.cc: Try unlink_nt first Ben Wijen
2021-01-26 11:46   ` Corinna Vinschen
2021-01-27  9:22     ` Ben
2021-01-20 16:10 ` [PATCH v2 8/8] fhandler_disk_file.cc: Use path_conv's IndexNumber Ben Wijen
2021-01-26 12:15   ` Corinna Vinschen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210115134534.13290-10-ben@wijen.net \
    --to=ben@wijen.net \
    --cc=cygwin-patches@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).