Merge tag '5.13-rc-smb3-part3' of git://git.samba.org/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 9 May 2021 20:19:29 +0000 (13:19 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 9 May 2021 20:19:29 +0000 (13:19 -0700)
Pull cifs fixes from Steve French:
 "Three small SMB3 chmultichannel related changesets (also for stable)
  from the SMB3 test event this week.

  The other fixes are still in review/testing"

* tag '5.13-rc-smb3-part3' of git://git.samba.org/sfrench/cifs-2.6:
  smb3: if max_channels set to more than one channel request multichannel
  smb3: do not attempt multichannel to server which does not support it
  smb3: when mounting with multichannel include it in requested capabilities

fs/cifs/fs_context.c
fs/cifs/sess.c
fs/cifs/smb2pdu.c

index 3bcf881..5d21cd9 100644 (file)
@@ -1021,6 +1021,9 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
                        goto cifs_parse_mount_err;
                }
                ctx->max_channels = result.uint_32;
+               /* If more than one channel requested ... they want multichan */
+               if (result.uint_32 > 1)
+                       ctx->multichannel = true;
                break;
        case Opt_handletimeout:
                ctx->handle_timeout = result.uint_32;
index 63d517b..a92a1fb 100644 (file)
@@ -97,6 +97,12 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
                return 0;
        }
 
+       if (!(ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
+               cifs_dbg(VFS, "server %s does not support multichannel\n", ses->server->hostname);
+               ses->chan_max = 1;
+               return 0;
+       }
+
        /*
         * Make a copy of the iface list at the time and use that
         * instead so as to not hold the iface spinlock for opening
index e36c2a8..a8bf431 100644 (file)
@@ -841,6 +841,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
                req->SecurityMode = 0;
 
        req->Capabilities = cpu_to_le32(server->vals->req_capabilities);
+       if (ses->chan_max > 1)
+               req->Capabilities |= cpu_to_le32(SMB2_GLOBAL_CAP_MULTI_CHANNEL);
 
        /* ClientGUID must be zero for SMB2.02 dialect */
        if (server->vals->protocol_id == SMB20_PROT_ID)
@@ -1032,6 +1034,9 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
 
        pneg_inbuf->Capabilities =
                        cpu_to_le32(server->vals->req_capabilities);
+       if (tcon->ses->chan_max > 1)
+               pneg_inbuf->Capabilities |= cpu_to_le32(SMB2_GLOBAL_CAP_MULTI_CHANNEL);
+
        memcpy(pneg_inbuf->Guid, server->client_guid,
                                        SMB2_CLIENT_GUID_SIZE);