Skip to content

Commit b5013d0

Browse files
committed
Merge tag '5.16-rc-part1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs updates from Steve French: - reconnect fix for stable - minor mount option fix - debugging improvement for (TCP) connection issues - refactoring of common code to help ksmbd * tag '5.16-rc-part1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: smb3: add dynamic trace points for socket connection cifs: Move SMB2_Create definitions to the shared area cifs: Move more definitions into the shared area cifs: move NEGOTIATE_PROTOCOL definitions out into the common area cifs: Create a new shared file holding smb2 pdu definitions cifs: add mount parameter tcpnodelay cifs: To match file servers, make sure the server hostname matches
2 parents 2acda75 + d7171cd commit b5013d0

File tree

15 files changed

+1299
-1091
lines changed

15 files changed

+1299
-1091
lines changed

fs/cifs/cifsfs.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
#include <linux/key-type.h>
3939
#include "cifs_spnego.h"
4040
#include "fscache.h"
41-
#include "smb2pdu.h"
4241
#ifdef CONFIG_CIFS_DFS_UPCALL
4342
#include "dfs_cache.h"
4443
#endif

fs/cifs/cifsglob.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <crypto/internal/hash.h>
2121
#include <linux/scatterlist.h>
2222
#include <uapi/linux/cifs/cifs_mount.h>
23+
#include "../smbfs_common/smb2pdu.h"
2324
#include "smb2pdu.h"
2425

2526
#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
@@ -776,7 +777,7 @@ revert_current_mid(struct TCP_Server_Info *server, const unsigned int val)
776777

777778
static inline void
778779
revert_current_mid_from_hdr(struct TCP_Server_Info *server,
779-
const struct smb2_sync_hdr *shdr)
780+
const struct smb2_hdr *shdr)
780781
{
781782
unsigned int num = le16_to_cpu(shdr->CreditCharge);
782783

fs/cifs/connect.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed)
677677
static unsigned int
678678
smb2_get_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
679679
{
680-
struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer;
680+
struct smb2_hdr *shdr = (struct smb2_hdr *)buffer;
681681

682682
/*
683683
* SMB1 does not use credits.
@@ -794,7 +794,6 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
794794
*/
795795
}
796796

797-
kfree(server->hostname);
798797
kfree(server);
799798

800799
length = atomic_dec_return(&tcpSesAllocCount);
@@ -878,7 +877,7 @@ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
878877
static void
879878
smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
880879
{
881-
struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer;
880+
struct smb2_hdr *shdr = (struct smb2_hdr *)buffer;
882881
int scredits, in_flight;
883882

884883
/*
@@ -1235,6 +1234,9 @@ static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context *
12351234
if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
12361235
return 0;
12371236

1237+
if (strcasecmp(server->hostname, ctx->server_hostname))
1238+
return 0;
1239+
12381240
if (!match_address(server, addr,
12391241
(struct sockaddr *)&ctx->srcaddr))
12401242
return 0;
@@ -1336,6 +1338,7 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
13361338
kfree(server->session_key.response);
13371339
server->session_key.response = NULL;
13381340
server->session_key.len = 0;
1341+
kfree(server->hostname);
13391342

13401343
task = xchg(&server->tsk, NULL);
13411344
if (task)
@@ -1361,14 +1364,15 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx)
13611364
goto out_err;
13621365
}
13631366

1367+
tcp_ses->hostname = kstrdup(ctx->server_hostname, GFP_KERNEL);
1368+
if (!tcp_ses->hostname) {
1369+
rc = -ENOMEM;
1370+
goto out_err;
1371+
}
1372+
13641373
tcp_ses->ops = ctx->ops;
13651374
tcp_ses->vals = ctx->vals;
13661375
cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
1367-
tcp_ses->hostname = extract_hostname(ctx->UNC);
1368-
if (IS_ERR(tcp_ses->hostname)) {
1369-
rc = PTR_ERR(tcp_ses->hostname);
1370-
goto out_err_crypto_release;
1371-
}
13721376

13731377
tcp_ses->conn_id = atomic_inc_return(&tcpSesNextId);
13741378
tcp_ses->noblockcnt = ctx->rootfs;
@@ -1497,8 +1501,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx)
14971501

14981502
out_err:
14991503
if (tcp_ses) {
1500-
if (!IS_ERR(tcp_ses->hostname))
1501-
kfree(tcp_ses->hostname);
1504+
kfree(tcp_ses->hostname);
15021505
if (tcp_ses->ssocket)
15031506
sock_release(tcp_ses->ssocket);
15041507
kfree(tcp_ses);
@@ -2646,11 +2649,12 @@ generic_ip_connect(struct TCP_Server_Info *server)
26462649
rc = 0;
26472650
if (rc < 0) {
26482651
cifs_dbg(FYI, "Error %d connecting to server\n", rc);
2652+
trace_smb3_connect_err(server->hostname, server->conn_id, &server->dstaddr, rc);
26492653
sock_release(socket);
26502654
server->ssocket = NULL;
26512655
return rc;
26522656
}
2653-
2657+
trace_smb3_connect_done(server->hostname, server->conn_id, &server->dstaddr);
26542658
if (sport == htons(RFC1001_PORT))
26552659
rc = ip_rfc1001_connect(server);
26562660

fs/cifs/fs_context.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {
116116
fsparam_flag("nosharesock", Opt_nosharesock),
117117
fsparam_flag_no("persistenthandles", Opt_persistent),
118118
fsparam_flag_no("resilienthandles", Opt_resilient),
119+
fsparam_flag_no("tcpnodelay", Opt_tcp_nodelay),
119120
fsparam_flag("domainauto", Opt_domainauto),
120121
fsparam_flag("rdma", Opt_rdma),
121122
fsparam_flag("modesid", Opt_modesid),
@@ -318,6 +319,7 @@ smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx
318319
DUP_CTX_STR(mount_options);
319320
DUP_CTX_STR(username);
320321
DUP_CTX_STR(password);
322+
DUP_CTX_STR(server_hostname);
321323
DUP_CTX_STR(UNC);
322324
DUP_CTX_STR(source);
323325
DUP_CTX_STR(domainname);
@@ -456,6 +458,11 @@ smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx)
456458
if (!pos)
457459
return -EINVAL;
458460

461+
/* record the server hostname */
462+
ctx->server_hostname = kstrndup(devname + 2, pos - devname - 2, GFP_KERNEL);
463+
if (!ctx->server_hostname)
464+
return -ENOMEM;
465+
459466
/* skip past delimiter */
460467
++pos;
461468

@@ -1383,6 +1390,13 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
13831390
}
13841391
}
13851392
break;
1393+
case Opt_tcp_nodelay:
1394+
/* tcp nodelay should not usually be needed since we CORK/UNCORK the socket */
1395+
if (result.negated)
1396+
ctx->sockopt_tcp_nodelay = false;
1397+
else
1398+
ctx->sockopt_tcp_nodelay = true;
1399+
break;
13861400
case Opt_domainauto:
13871401
ctx->domainauto = true;
13881402
break;
@@ -1496,6 +1510,8 @@ smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx)
14961510
ctx->username = NULL;
14971511
kfree_sensitive(ctx->password);
14981512
ctx->password = NULL;
1513+
kfree(ctx->server_hostname);
1514+
ctx->server_hostname = NULL;
14991515
kfree(ctx->UNC);
15001516
ctx->UNC = NULL;
15011517
kfree(ctx->source);

fs/cifs/fs_context.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ enum cifs_param {
9898
Opt_nosharesock,
9999
Opt_persistent,
100100
Opt_resilient,
101+
Opt_tcp_nodelay,
101102
Opt_domainauto,
102103
Opt_rdma,
103104
Opt_modesid,
@@ -166,6 +167,7 @@ struct smb3_fs_context {
166167
char *password;
167168
char *domainname;
168169
char *source;
170+
char *server_hostname;
169171
char *UNC;
170172
char *nodename;
171173
char *iocharset; /* local code page for mapping to and from Unicode */

fs/cifs/misc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ cifs_buf_get(void)
152152
* SMB2 header is bigger than CIFS one - no problems to clean some
153153
* more bytes for CIFS.
154154
*/
155-
size_t buf_size = sizeof(struct smb2_sync_hdr);
155+
size_t buf_size = sizeof(struct smb2_hdr);
156156

157157
/*
158158
* We could use negotiated size instead of max_msgsize -

fs/cifs/smb2maperror.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2439,14 +2439,16 @@ smb2_print_status(__le32 status)
24392439
int
24402440
map_smb2_to_linux_error(char *buf, bool log_err)
24412441
{
2442-
struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
2442+
struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
24432443
unsigned int i;
24442444
int rc = -EIO;
24452445
__le32 smb2err = shdr->Status;
24462446

24472447
if (smb2err == 0) {
2448-
trace_smb3_cmd_done(shdr->TreeId, shdr->SessionId,
2449-
le16_to_cpu(shdr->Command), le64_to_cpu(shdr->MessageId));
2448+
trace_smb3_cmd_done(le32_to_cpu(shdr->Id.SyncId.TreeId),
2449+
le64_to_cpu(shdr->SessionId),
2450+
le16_to_cpu(shdr->Command),
2451+
le64_to_cpu(shdr->MessageId));
24502452
return 0;
24512453
}
24522454

@@ -2470,8 +2472,10 @@ map_smb2_to_linux_error(char *buf, bool log_err)
24702472
cifs_dbg(FYI, "Mapping SMB2 status code 0x%08x to POSIX err %d\n",
24712473
__le32_to_cpu(smb2err), rc);
24722474

2473-
trace_smb3_cmd_err(shdr->TreeId, shdr->SessionId,
2474-
le16_to_cpu(shdr->Command),
2475-
le64_to_cpu(shdr->MessageId), le32_to_cpu(smb2err), rc);
2475+
trace_smb3_cmd_err(le32_to_cpu(shdr->Id.SyncId.TreeId),
2476+
le64_to_cpu(shdr->SessionId),
2477+
le16_to_cpu(shdr->Command),
2478+
le64_to_cpu(shdr->MessageId),
2479+
le32_to_cpu(smb2err), rc);
24762480
return rc;
24772481
}

fs/cifs/smb2misc.c

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
*
99
*/
1010
#include <linux/ctype.h>
11-
#include "smb2pdu.h"
1211
#include "cifsglob.h"
1312
#include "cifsproto.h"
1413
#include "smb2proto.h"
@@ -19,7 +18,7 @@
1918
#include "nterr.h"
2019

2120
static int
22-
check_smb2_hdr(struct smb2_sync_hdr *shdr, __u64 mid)
21+
check_smb2_hdr(struct smb2_hdr *shdr, __u64 mid)
2322
{
2423
__u64 wire_mid = le64_to_cpu(shdr->MessageId);
2524

@@ -81,9 +80,9 @@ static const __le16 smb2_rsp_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
8180
/* SMB2_OPLOCK_BREAK */ cpu_to_le16(24)
8281
};
8382

84-
#define SMB311_NEGPROT_BASE_SIZE (sizeof(struct smb2_sync_hdr) + sizeof(struct smb2_negotiate_rsp))
83+
#define SMB311_NEGPROT_BASE_SIZE (sizeof(struct smb2_hdr) + sizeof(struct smb2_negotiate_rsp))
8584

86-
static __u32 get_neg_ctxt_len(struct smb2_sync_hdr *hdr, __u32 len,
85+
static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len,
8786
__u32 non_ctxlen)
8887
{
8988
__u16 neg_count;
@@ -135,13 +134,13 @@ static __u32 get_neg_ctxt_len(struct smb2_sync_hdr *hdr, __u32 len,
135134
int
136135
smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
137136
{
138-
struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf;
139-
struct smb2_sync_pdu *pdu = (struct smb2_sync_pdu *)shdr;
137+
struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
138+
struct smb2_pdu *pdu = (struct smb2_pdu *)shdr;
140139
__u64 mid;
141140
__u32 clc_len; /* calculated length */
142141
int command;
143-
int pdu_size = sizeof(struct smb2_sync_pdu);
144-
int hdr_size = sizeof(struct smb2_sync_hdr);
142+
int pdu_size = sizeof(struct smb2_pdu);
143+
int hdr_size = sizeof(struct smb2_hdr);
145144

146145
/*
147146
* Add function to do table lookup of StructureSize by command
@@ -155,7 +154,7 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
155154
/* decrypt frame now that it is completely read in */
156155
spin_lock(&cifs_tcp_ses_lock);
157156
list_for_each_entry(ses, &srvr->smb_ses_list, smb_ses_list) {
158-
if (ses->Suid == thdr->SessionId)
157+
if (ses->Suid == le64_to_cpu(thdr->SessionId))
159158
break;
160159
}
161160
spin_unlock(&cifs_tcp_ses_lock);
@@ -296,7 +295,7 @@ static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = {
296295
* area and the offset to it (from the beginning of the smb are also returned.
297296
*/
298297
char *
299-
smb2_get_data_area_len(int *off, int *len, struct smb2_sync_hdr *shdr)
298+
smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *shdr)
300299
{
301300
*off = 0;
302301
*len = 0;
@@ -401,8 +400,8 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_sync_hdr *shdr)
401400
unsigned int
402401
smb2_calc_size(void *buf, struct TCP_Server_Info *srvr)
403402
{
404-
struct smb2_sync_pdu *pdu = (struct smb2_sync_pdu *)buf;
405-
struct smb2_sync_hdr *shdr = &pdu->sync_hdr;
403+
struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
404+
struct smb2_hdr *shdr = &pdu->hdr;
406405
int offset; /* the offset from the beginning of SMB to data area */
407406
int data_length; /* the length of the variable length data area */
408407
/* Structure Size has already been checked to make sure it is 64 */
@@ -669,7 +668,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
669668

670669
cifs_dbg(FYI, "Checking for oplock break\n");
671670

672-
if (rsp->sync_hdr.Command != SMB2_OPLOCK_BREAK)
671+
if (rsp->hdr.Command != SMB2_OPLOCK_BREAK)
673672
return false;
674673

675674
if (rsp->StructureSize !=
@@ -816,25 +815,25 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
816815
int
817816
smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server)
818817
{
819-
struct smb2_sync_hdr *sync_hdr = mid->resp_buf;
818+
struct smb2_hdr *hdr = mid->resp_buf;
820819
struct smb2_create_rsp *rsp = mid->resp_buf;
821820
struct cifs_tcon *tcon;
822821
int rc;
823822

824-
if ((mid->optype & CIFS_CP_CREATE_CLOSE_OP) || sync_hdr->Command != SMB2_CREATE ||
825-
sync_hdr->Status != STATUS_SUCCESS)
823+
if ((mid->optype & CIFS_CP_CREATE_CLOSE_OP) || hdr->Command != SMB2_CREATE ||
824+
hdr->Status != STATUS_SUCCESS)
826825
return 0;
827826

828-
tcon = smb2_find_smb_tcon(server, sync_hdr->SessionId,
829-
sync_hdr->TreeId);
827+
tcon = smb2_find_smb_tcon(server, le64_to_cpu(hdr->SessionId),
828+
le32_to_cpu(hdr->Id.SyncId.TreeId));
830829
if (!tcon)
831830
return -ENOENT;
832831

833832
rc = __smb2_handle_cancelled_cmd(tcon,
834-
le16_to_cpu(sync_hdr->Command),
835-
le64_to_cpu(sync_hdr->MessageId),
836-
rsp->PersistentFileId,
837-
rsp->VolatileFileId);
833+
le16_to_cpu(hdr->Command),
834+
le64_to_cpu(hdr->MessageId),
835+
le64_to_cpu(rsp->PersistentFileId),
836+
le64_to_cpu(rsp->VolatileFileId));
838837
if (rc)
839838
cifs_put_tcon(tcon);
840839

@@ -856,10 +855,10 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct kvec *iov, int nvec)
856855
{
857856
int i, rc;
858857
struct sdesc *d;
859-
struct smb2_sync_hdr *hdr;
858+
struct smb2_hdr *hdr;
860859
struct TCP_Server_Info *server = cifs_ses_server(ses);
861860

862-
hdr = (struct smb2_sync_hdr *)iov[0].iov_base;
861+
hdr = (struct smb2_hdr *)iov[0].iov_base;
863862
/* neg prot are always taken */
864863
if (hdr->Command == SMB2_NEGOTIATE)
865864
goto ok;

0 commit comments

Comments
 (0)