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