[PATCH][CIFS] Fix match_server check to allow for multidialect negotiate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When using multidialect negotiate (default or allowing any smb3
dialect via vers=3)
allow matching on existing server session.  Before this fix if you mount
a second time to a different share on the same server, we will only reuse
the existing smb session if a single dialect is requested (e.g. specifying
vers=2.1 or vers=3.0 or vers=3.1.1 on the mount command). If a default mount
(e.g. not specifying vers=) is done then we will create a new socket
connection and SMB3 (or SMB3.1.1) session each time we connect to a
different share
on the same server rather than reusing the existing one.

Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx>
---
 fs/cifs/connect.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 8c4121da624e..6200207565db 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2542,8 +2542,25 @@ static int match_server(struct TCP_Server_Info
*server, struct smb_vol *vol)
     if (vol->nosharesock)
         return 0;

-    /* BB update this for smb3any and default case */
-    if ((server->vals != vol->vals) || (server->ops != vol->ops))
+    /* If multidialect negotiation see if existing sessions match one */
+    if (strcmp(vol->vals->version_string, SMB3ANY_VERSION_STRING) == 0) {
+        if (server->vals->protocol_id == SMB20_PROT_ID)
+            return 0;
+        else if (server->vals->protocol_id == SMB21_PROT_ID)
+            return 0;
+        else if (strcmp(server->vals->version_string,
+             SMB1_VERSION_STRING) == 0)
+            return 0;
+        /* else SMB3 or later, which is fine */
+    } else if (strcmp(vol->vals->version_string,
+           SMBDEFAULT_VERSION_STRING) == 0) {
+        if (server->vals->protocol_id == SMB20_PROT_ID)
+            return 0;
+        else if (strcmp(server->vals->version_string,
+             SMB1_VERSION_STRING) == 0)
+            return 0;
+        /* else SMB2.1 or later, which is fine */
+    } else if ((server->vals != vol->vals) || (server->ops != vol->ops))
         return 0;

     if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
-- 
2.20.1


-- 
Thanks,

Steve
From fd5e01a89742bb85d758a6651294a8a20193bc27 Mon Sep 17 00:00:00 2001
From: Steve French <stfrench@xxxxxxxxxxxxx>
Date: Sat, 8 Jun 2019 03:56:29 -0500
Subject: [PATCH] [CIFS] Fix match_server check to allow for multidialect
 negotiate

When using multidialect negotiate (default or allowing any smb3 dialect via vers=3)
allow matching on existing server session.  Before this fix if you mount
a second time to a different share on the same server, we will only reuse
the existing smb session if a single dialect is requested (e.g. specifying
vers=2.1 or vers=3.0 or vers=3.1.1 on the mount command). If a default mount
(e.g. not specifying vers=) is done then we will create a new socket
connection and SMB3 (or SMB3.1.1) session each time we connect to a different share
on the same server rather than reusing the existing one.

Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx>
---
 fs/cifs/connect.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 8c4121da624e..6200207565db 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2542,8 +2542,25 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
 	if (vol->nosharesock)
 		return 0;
 
-	/* BB update this for smb3any and default case */
-	if ((server->vals != vol->vals) || (server->ops != vol->ops))
+	/* If multidialect negotiation see if existing sessions match one */
+	if (strcmp(vol->vals->version_string, SMB3ANY_VERSION_STRING) == 0) {
+		if (server->vals->protocol_id == SMB20_PROT_ID)
+			return 0;
+		else if (server->vals->protocol_id == SMB21_PROT_ID)
+			return 0;
+		else if (strcmp(server->vals->version_string,
+			 SMB1_VERSION_STRING) == 0)
+			return 0;
+		/* else SMB3 or later, which is fine */
+	} else if (strcmp(vol->vals->version_string,
+		   SMBDEFAULT_VERSION_STRING) == 0) {
+		if (server->vals->protocol_id == SMB20_PROT_ID)
+			return 0;
+		else if (strcmp(server->vals->version_string,
+			 SMB1_VERSION_STRING) == 0)
+			return 0;
+		/* else SMB2.1 or later, which is fine */
+	} else if ((server->vals != vol->vals) || (server->ops != vol->ops))
 		return 0;
 
 	if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
-- 
2.20.1


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux