Skip to content

Commit f7950cb

Browse files
longlimsftsmfrench
authored andcommitted
cifs: smbd: Calculate the correct maximum packet size for segmented SMBDirect send/receive
The packet size needs to take account of SMB2 header size and possible encryption header size. This is only done when signing is used and it is for RDMA send/receive, not read/write. Also remove the dead SMBD code in smb2_negotiate_r(w)size. Signed-off-by: Long Li <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent edad734 commit f7950cb

File tree

3 files changed

+20
-24
lines changed

3 files changed

+20
-24
lines changed

fs/cifs/smb2ops.c

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -328,16 +328,6 @@ smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
328328
/* start with specified wsize, or default */
329329
wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE;
330330
wsize = min_t(unsigned int, wsize, server->max_write);
331-
#ifdef CONFIG_CIFS_SMB_DIRECT
332-
if (server->rdma) {
333-
if (server->sign)
334-
wsize = min_t(unsigned int,
335-
wsize, server->smbd_conn->max_fragmented_send_size);
336-
else
337-
wsize = min_t(unsigned int,
338-
wsize, server->smbd_conn->max_readwrite_size);
339-
}
340-
#endif
341331
if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
342332
wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE);
343333

@@ -356,8 +346,15 @@ smb3_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
356346
#ifdef CONFIG_CIFS_SMB_DIRECT
357347
if (server->rdma) {
358348
if (server->sign)
349+
/*
350+
* Account for SMB2 data transfer packet header and
351+
* possible encryption header
352+
*/
359353
wsize = min_t(unsigned int,
360-
wsize, server->smbd_conn->max_fragmented_send_size);
354+
wsize,
355+
server->smbd_conn->max_fragmented_send_size -
356+
SMB2_READWRITE_PDU_HEADER_SIZE -
357+
sizeof(struct smb2_transform_hdr));
361358
else
362359
wsize = min_t(unsigned int,
363360
wsize, server->smbd_conn->max_readwrite_size);
@@ -378,16 +375,6 @@ smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
378375
/* start with specified rsize, or default */
379376
rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE;
380377
rsize = min_t(unsigned int, rsize, server->max_read);
381-
#ifdef CONFIG_CIFS_SMB_DIRECT
382-
if (server->rdma) {
383-
if (server->sign)
384-
rsize = min_t(unsigned int,
385-
rsize, server->smbd_conn->max_fragmented_recv_size);
386-
else
387-
rsize = min_t(unsigned int,
388-
rsize, server->smbd_conn->max_readwrite_size);
389-
}
390-
#endif
391378

392379
if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
393380
rsize = min_t(unsigned int, rsize, SMB2_MAX_BUFFER_SIZE);
@@ -407,8 +394,15 @@ smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
407394
#ifdef CONFIG_CIFS_SMB_DIRECT
408395
if (server->rdma) {
409396
if (server->sign)
397+
/*
398+
* Account for SMB2 data transfer packet header and
399+
* possible encryption header
400+
*/
410401
rsize = min_t(unsigned int,
411-
rsize, server->smbd_conn->max_fragmented_recv_size);
402+
rsize,
403+
server->smbd_conn->max_fragmented_recv_size -
404+
SMB2_READWRITE_PDU_HEADER_SIZE -
405+
sizeof(struct smb2_transform_hdr));
412406
else
413407
rsize = min_t(unsigned int,
414408
rsize, server->smbd_conn->max_readwrite_size);

fs/cifs/smb2pdu.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ struct smb2_sync_hdr {
120120
__u8 Signature[16];
121121
} __packed;
122122

123+
/* The total header size for SMB2 read and write */
124+
#define SMB2_READWRITE_PDU_HEADER_SIZE (48 + sizeof(struct smb2_sync_hdr))
125+
123126
struct smb2_sync_pdu {
124127
struct smb2_sync_hdr sync_hdr;
125128
__le16 StructureSize2; /* size of wct area (varies, request specific) */

fs/cifs/smbdirect.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,8 +2097,7 @@ int smbd_send(struct TCP_Server_Info *server,
20972097
for (i = 0; i < num_rqst; i++)
20982098
remaining_data_length += smb_rqst_len(server, &rqst_array[i]);
20992099

2100-
if (remaining_data_length + sizeof(struct smbd_data_transfer) >
2101-
info->max_fragmented_send_size) {
2100+
if (remaining_data_length > info->max_fragmented_send_size) {
21022101
log_write(ERR, "payload size %d > max size %d\n",
21032102
remaining_data_length, info->max_fragmented_send_size);
21042103
rc = -EINVAL;

0 commit comments

Comments
 (0)