All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paulo Alcantara <pc@cjr.nz>
To: linux-cifs@vger.kernel.org, smfrench@gmail.com
Cc: Paulo Alcantara <pc@cjr.nz>
Subject: [PATCH v2 2/7] cifs: reduce number of referral requests in DFS link lookups
Date: Mon,  6 Jul 2020 15:16:04 -0300	[thread overview]
Message-ID: <20200706181609.19480-3-pc@cjr.nz> (raw)
In-Reply-To: <20200706181609.19480-1-pc@cjr.nz>

When looking up the DFS cache with a referral path that has more than
two path components, and is a complete prefix of an existing cache
entry, do not request another referral and just return the matched
entry as specified in MS-DFSC 3.2.5.5 Receiving a Root Referral
Request or Link Referral Request.

Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
---
 fs/cifs/dfs_cache.c | 79 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 68 insertions(+), 11 deletions(-)

diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c
index df81c718d2fa..dae2f41e4f21 100644
--- a/fs/cifs/dfs_cache.c
+++ b/fs/cifs/dfs_cache.c
@@ -490,16 +490,7 @@ static int add_cache_entry(const char *path, unsigned int hash,
 	return 0;
 }
 
-/*
- * Find a DFS cache entry in hash table and optionally check prefix path against
- * @path.
- * Use whole path components in the match.
- * Must be called with htable_rw_lock held.
- *
- * Return ERR_PTR(-ENOENT) if the entry is not found.
- */
-static struct cache_entry *lookup_cache_entry(const char *path,
-					      unsigned int *hash)
+static struct cache_entry *__lookup_cache_entry(const char *path)
 {
 	struct cache_entry *ce;
 	unsigned int h;
@@ -517,9 +508,75 @@ static struct cache_entry *lookup_cache_entry(const char *path,
 
 	if (!found)
 		ce = ERR_PTR(-ENOENT);
+	return ce;
+}
+
+/*
+ * Find a DFS cache entry in hash table and optionally check prefix path against
+ * @path.
+ * Use whole path components in the match.
+ * Must be called with htable_rw_lock held.
+ *
+ * Return ERR_PTR(-ENOENT) if the entry is not found.
+ */
+static struct cache_entry *lookup_cache_entry(const char *path, unsigned int *hash)
+{
+	struct cache_entry *ce = ERR_PTR(-ENOENT);
+	unsigned int h;
+	int cnt = 0;
+	char *npath;
+	char *s, *e;
+	char sep;
+
+	npath = kstrndup(path, strlen(path), GFP_KERNEL);
+	if (!npath)
+		return ERR_PTR(-ENOMEM);
+
+	s = npath;
+	sep = *npath;
+	while ((s = strchr(s, sep)) && ++cnt < 3)
+		s++;
+
+	if (cnt < 3) {
+		h = cache_entry_hash(path, strlen(path));
+		ce = __lookup_cache_entry(path);
+		goto out;
+	}
+	/*
+	 * Handle paths that have more than two path components and are a complete prefix of the DFS
+	 * referral request path (@path).
+	 *
+	 * See MS-DFSC 3.2.5.5 "Receiving a Root Referral Request or Link Referral Request".
+	 */
+	h = cache_entry_hash(npath, strlen(npath));
+	e = npath + strlen(npath) - 1;
+	while (e > s) {
+		char tmp;
+
+		/* skip separators */
+		while (e > s && *e == sep)
+			e--;
+		if (e == s)
+			goto out;
+
+		tmp = *(e+1);
+		*(e+1) = 0;
+
+		ce = __lookup_cache_entry(npath);
+		if (!IS_ERR(ce)) {
+			h = cache_entry_hash(npath, strlen(npath));
+			break;
+		}
+
+		*(e+1) = tmp;
+		/* backward until separator */
+		while (e > s && *e != sep)
+			e--;
+	}
+out:
 	if (hash)
 		*hash = h;
-
+	kfree(npath);
 	return ce;
 }
 
-- 
2.27.0


  parent reply	other threads:[~2020-07-06 18:16 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-06 18:16 [PATCH v2 0/7] DFS fixes Paulo Alcantara
2020-07-06 18:16 ` [PATCH v2 1/7] cifs: merge __{cifs,smb2}_reconnect[_tcon]() into cifs_tree_connect() Paulo Alcantara
2020-07-09 14:54   ` Aurélien Aptel
2020-07-06 18:16 ` Paulo Alcantara [this message]
2020-07-09 14:52   ` [PATCH v2 2/7] cifs: reduce number of referral requests in DFS link lookups Aurélien Aptel
2020-07-06 18:16 ` [PATCH v2 3/7] cifs: rename reconn_inval_dfs_target() Paulo Alcantara
2020-07-09 14:55   ` Aurélien Aptel
2020-07-06 18:16 ` [PATCH v2 4/7] cifs: handle empty list of targets in cifs_reconnect() Paulo Alcantara
2020-07-09 15:38   ` Aurélien Aptel
2020-07-06 18:16 ` [PATCH v2 5/7] cifs: handle RESP_GET_DFS_REFERRAL.PathConsumed in reconnect Paulo Alcantara
2020-07-06 18:16 ` [PATCH v2 6/7] cifs: only update prefix path of DFS links in cifs_tree_connect() Paulo Alcantara
2020-07-06 18:16 ` [PATCH v2 7/7] cifs: document and cleanup dfs mount Paulo Alcantara
2020-07-09 14:49   ` Aurélien Aptel

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=20200706181609.19480-3-pc@cjr.nz \
    --to=pc@cjr.nz \
    --cc=linux-cifs@vger.kernel.org \
    --cc=smfrench@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.