Skip to content

Commit 1944f6a

Browse files
metze-sambaSteve French
authored andcommitted
smb: client: let smbd_post_send_iter() respect the peers max_send_size and transmit all data
We should not send smbdirect_data_transfer messages larger than the negotiated max_send_size, typically 1364 bytes, which means 24 bytes of the smbdirect_data_transfer header + 1340 payload bytes. This happened when doing an SMB2 write with more than 1340 bytes (which is done inline as it's below rdma_readwrite_threshold). It means the peer resets the connection. When testing between cifs.ko and ksmbd.ko something like this is logged: client: CIFS: VFS: RDMA transport re-established siw: got TERMINATE. layer 1, type 2, code 2 siw: got TERMINATE. layer 1, type 2, code 2 siw: got TERMINATE. layer 1, type 2, code 2 siw: got TERMINATE. layer 1, type 2, code 2 siw: got TERMINATE. layer 1, type 2, code 2 siw: got TERMINATE. layer 1, type 2, code 2 siw: got TERMINATE. layer 1, type 2, code 2 siw: got TERMINATE. layer 1, type 2, code 2 siw: got TERMINATE. layer 1, type 2, code 2 CIFS: VFS: \\carina Send error in SessSetup = -11 smb2_reconnect: 12 callbacks suppressed CIFS: VFS: reconnect tcon failed rc = -11 CIFS: VFS: reconnect tcon failed rc = -11 CIFS: VFS: reconnect tcon failed rc = -11 CIFS: VFS: SMB: Zero rsize calculated, using minimum value 65536 and: CIFS: VFS: RDMA transport re-established siw: got TERMINATE. layer 1, type 2, code 2 CIFS: VFS: smbd_recv:1894 disconnected siw: got TERMINATE. layer 1, type 2, code 2 The ksmbd dmesg is showing things like: smb_direct: Recv error. status='local length error (1)' opcode=128 smb_direct: disconnected smb_direct: Recv error. status='local length error (1)' opcode=128 ksmbd: smb_direct: disconnected ksmbd: sock_read failed: -107 As smbd_post_send_iter() limits the transmitted number of bytes we need loop over it in order to transmit the whole iter. Reviewed-by: David Howells <[email protected]> Tested-by: David Howells <[email protected]> Tested-by: Meetakshi Setiya <[email protected]> Cc: Tom Talpey <[email protected]> Cc: [email protected] Cc: <[email protected]> # sp->max_send_size should be info->max_send_size in backports Fixes: 3d78fe7 ("cifs: Build the RDMA SGE list directly from an iterator") Signed-off-by: Stefan Metzmacher <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent ff8abbd commit 1944f6a

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

fs/smb/client/smbdirect.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -907,8 +907,10 @@ static int smbd_post_send_iter(struct smbd_connection *info,
907907
.local_dma_lkey = sc->ib.pd->local_dma_lkey,
908908
.direction = DMA_TO_DEVICE,
909909
};
910+
size_t payload_len = umin(*_remaining_data_length,
911+
sp->max_send_size - sizeof(*packet));
910912

911-
rc = smb_extract_iter_to_rdma(iter, *_remaining_data_length,
913+
rc = smb_extract_iter_to_rdma(iter, payload_len,
912914
&extract);
913915
if (rc < 0)
914916
goto err_dma;
@@ -1013,6 +1015,27 @@ static int smbd_post_send_empty(struct smbd_connection *info)
10131015
return smbd_post_send_iter(info, NULL, &remaining_data_length);
10141016
}
10151017

1018+
static int smbd_post_send_full_iter(struct smbd_connection *info,
1019+
struct iov_iter *iter,
1020+
int *_remaining_data_length)
1021+
{
1022+
int rc = 0;
1023+
1024+
/*
1025+
* smbd_post_send_iter() respects the
1026+
* negotiated max_send_size, so we need to
1027+
* loop until the full iter is posted
1028+
*/
1029+
1030+
while (iov_iter_count(iter) > 0) {
1031+
rc = smbd_post_send_iter(info, iter, _remaining_data_length);
1032+
if (rc < 0)
1033+
break;
1034+
}
1035+
1036+
return rc;
1037+
}
1038+
10161039
/*
10171040
* Post a receive request to the transport
10181041
* The remote peer can only send data when a receive request is posted
@@ -2032,14 +2055,14 @@ int smbd_send(struct TCP_Server_Info *server,
20322055
klen += rqst->rq_iov[i].iov_len;
20332056
iov_iter_kvec(&iter, ITER_SOURCE, rqst->rq_iov, rqst->rq_nvec, klen);
20342057

2035-
rc = smbd_post_send_iter(info, &iter, &remaining_data_length);
2058+
rc = smbd_post_send_full_iter(info, &iter, &remaining_data_length);
20362059
if (rc < 0)
20372060
break;
20382061

20392062
if (iov_iter_count(&rqst->rq_iter) > 0) {
20402063
/* And then the data pages if there are any */
2041-
rc = smbd_post_send_iter(info, &rqst->rq_iter,
2042-
&remaining_data_length);
2064+
rc = smbd_post_send_full_iter(info, &rqst->rq_iter,
2065+
&remaining_data_length);
20432066
if (rc < 0)
20442067
break;
20452068
}

0 commit comments

Comments
 (0)