97
97
Opt_persistent , Opt_nopersistent ,
98
98
Opt_resilient , Opt_noresilient ,
99
99
Opt_domainauto , Opt_rdma , Opt_modesid , Opt_rootfs ,
100
+ Opt_multichannel , Opt_nomultichannel ,
100
101
Opt_compress ,
101
102
102
103
/* Mount options which take numeric value */
@@ -106,7 +107,7 @@ enum {
106
107
Opt_min_enc_offload ,
107
108
Opt_blocksize , Opt_rsize , Opt_wsize , Opt_actimeo ,
108
109
Opt_echo_interval , Opt_max_credits , Opt_handletimeout ,
109
- Opt_snapshot ,
110
+ Opt_snapshot , Opt_max_channels ,
110
111
111
112
/* Mount options which take string value */
112
113
Opt_user , Opt_pass , Opt_ip ,
@@ -199,6 +200,8 @@ static const match_table_t cifs_mount_option_tokens = {
199
200
{ Opt_noresilient , "noresilienthandles" },
200
201
{ Opt_domainauto , "domainauto" },
201
202
{ Opt_rdma , "rdma" },
203
+ { Opt_multichannel , "multichannel" },
204
+ { Opt_nomultichannel , "nomultichannel" },
202
205
203
206
{ Opt_backupuid , "backupuid=%s" },
204
207
{ Opt_backupgid , "backupgid=%s" },
@@ -218,6 +221,7 @@ static const match_table_t cifs_mount_option_tokens = {
218
221
{ Opt_echo_interval , "echo_interval=%s" },
219
222
{ Opt_max_credits , "max_credits=%s" },
220
223
{ Opt_snapshot , "snapshot=%s" },
224
+ { Opt_max_channels , "max_channels=%s" },
221
225
{ Opt_compress , "compress=%s" },
222
226
223
227
{ Opt_blank_user , "user=" },
@@ -1681,6 +1685,10 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1681
1685
1682
1686
vol -> echo_interval = SMB_ECHO_INTERVAL_DEFAULT ;
1683
1687
1688
+ /* default to no multichannel (single server connection) */
1689
+ vol -> multichannel = false;
1690
+ vol -> max_channels = 1 ;
1691
+
1684
1692
if (!mountdata )
1685
1693
goto cifs_parse_mount_err ;
1686
1694
@@ -1974,6 +1982,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1974
1982
case Opt_rdma :
1975
1983
vol -> rdma = true;
1976
1984
break ;
1985
+ case Opt_multichannel :
1986
+ vol -> multichannel = true;
1987
+ break ;
1988
+ case Opt_nomultichannel :
1989
+ vol -> multichannel = false;
1990
+ break ;
1977
1991
case Opt_compress :
1978
1992
vol -> compression = UNKNOWN_TYPE ;
1979
1993
cifs_dbg (VFS ,
@@ -2137,6 +2151,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
2137
2151
}
2138
2152
vol -> max_credits = option ;
2139
2153
break ;
2154
+ case Opt_max_channels :
2155
+ if (get_option_ul (args , & option ) || option < 1 ||
2156
+ option > CIFS_MAX_CHANNELS ) {
2157
+ cifs_dbg (VFS , "%s: Invalid max_channels value, needs to be 1-%d\n" ,
2158
+ __func__ , CIFS_MAX_CHANNELS );
2159
+ goto cifs_parse_mount_err ;
2160
+ }
2161
+ vol -> max_channels = option ;
2162
+ break ;
2140
2163
2141
2164
/* String Arguments */
2142
2165
@@ -2781,7 +2804,11 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
2781
2804
sizeof (tcp_ses -> srcaddr ));
2782
2805
memcpy (& tcp_ses -> dstaddr , & volume_info -> dstaddr ,
2783
2806
sizeof (tcp_ses -> dstaddr ));
2784
- generate_random_uuid (tcp_ses -> client_guid );
2807
+ if (volume_info -> use_client_guid )
2808
+ memcpy (tcp_ses -> client_guid , volume_info -> client_guid ,
2809
+ SMB2_CLIENT_GUID_SIZE );
2810
+ else
2811
+ generate_random_uuid (tcp_ses -> client_guid );
2785
2812
/*
2786
2813
* at this point we are the only ones with the pointer
2787
2814
* to the struct since the kernel thread not created yet
@@ -2870,6 +2897,13 @@ static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
2870
2897
vol -> sectype != ses -> sectype )
2871
2898
return 0 ;
2872
2899
2900
+ /*
2901
+ * If an existing session is limited to less channels than
2902
+ * requested, it should not be reused
2903
+ */
2904
+ if (ses -> chan_max < vol -> max_channels )
2905
+ return 0 ;
2906
+
2873
2907
switch (ses -> sectype ) {
2874
2908
case Kerberos :
2875
2909
if (!uid_eq (vol -> cred_uid , ses -> cred_uid ))
0 commit comments