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
next prev 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).