From a3d701cc8dba94f1b8a3c4ffcf71cd075bebe23c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jul 2025 15:28:37 +0200 Subject: [PATCH] 6.12-stable patches added patches: smb-client-let-smbd_post_send_iter-respect-the-peers-max_send_size-and-transmit-all-data.patch --- queue-6.12/series | 1 + ...-max_send_size-and-transmit-all-data.patch | 132 ++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 queue-6.12/smb-client-let-smbd_post_send_iter-respect-the-peers-max_send_size-and-transmit-all-data.patch diff --git a/queue-6.12/series b/queue-6.12/series index eb29b9017b..a57f9ed855 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -155,3 +155,4 @@ i2c-omap-fix-deprecated-of_property_read_bool-use.patch sched-freezer-remove-unnecessary-warning-in-__thaw_task.patch drm-xe-mocs-initialize-mocs-index-early.patch drm-xe-move-page-fault-init-after-topology-init.patch +smb-client-let-smbd_post_send_iter-respect-the-peers-max_send_size-and-transmit-all-data.patch diff --git a/queue-6.12/smb-client-let-smbd_post_send_iter-respect-the-peers-max_send_size-and-transmit-all-data.patch b/queue-6.12/smb-client-let-smbd_post_send_iter-respect-the-peers-max_send_size-and-transmit-all-data.patch new file mode 100644 index 0000000000..e3fddd7245 --- /dev/null +++ b/queue-6.12/smb-client-let-smbd_post_send_iter-respect-the-peers-max_send_size-and-transmit-all-data.patch @@ -0,0 +1,132 @@ +From 1944f6ab4967db7ad8d4db527dceae8c77de76e9 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +Date: Wed, 25 Jun 2025 10:16:38 +0200 +Subject: smb: client: let smbd_post_send_iter() respect the peers max_send_size and transmit all data + +From: Stefan Metzmacher + +commit 1944f6ab4967db7ad8d4db527dceae8c77de76e9 upstream. + +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 +Tested-by: David Howells +Tested-by: Meetakshi Setiya +Cc: Tom Talpey +Cc: linux-cifs@vger.kernel.org +Cc: # sp->max_send_size should be info->max_send_size in backports +Fixes: 3d78fe73fa12 ("cifs: Build the RDMA SGE list directly from an iterator") +Signed-off-by: Stefan Metzmacher +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/smbdirect.c | 31 +++++++++++++++++++++++++++---- + 1 file changed, 27 insertions(+), 4 deletions(-) + +--- a/fs/smb/client/smbdirect.c ++++ b/fs/smb/client/smbdirect.c +@@ -907,8 +907,10 @@ wait_send_queue: + .local_dma_lkey = sc->ib.pd->local_dma_lkey, + .direction = DMA_TO_DEVICE, + }; ++ size_t payload_len = umin(*_remaining_data_length, ++ sp->max_send_size - sizeof(*packet)); + +- rc = smb_extract_iter_to_rdma(iter, *_remaining_data_length, ++ rc = smb_extract_iter_to_rdma(iter, payload_len, + &extract); + if (rc < 0) + goto err_dma; +@@ -1013,6 +1015,27 @@ static int smbd_post_send_empty(struct s + return smbd_post_send_iter(info, NULL, &remaining_data_length); + } + ++static int smbd_post_send_full_iter(struct smbd_connection *info, ++ struct iov_iter *iter, ++ int *_remaining_data_length) ++{ ++ int rc = 0; ++ ++ /* ++ * smbd_post_send_iter() respects the ++ * negotiated max_send_size, so we need to ++ * loop until the full iter is posted ++ */ ++ ++ while (iov_iter_count(iter) > 0) { ++ rc = smbd_post_send_iter(info, iter, _remaining_data_length); ++ if (rc < 0) ++ break; ++ } ++ ++ return rc; ++} ++ + /* + * Post a receive request to the transport + * The remote peer can only send data when a receive request is posted +@@ -1962,14 +1985,14 @@ int smbd_send(struct TCP_Server_Info *se + klen += rqst->rq_iov[i].iov_len; + iov_iter_kvec(&iter, ITER_SOURCE, rqst->rq_iov, rqst->rq_nvec, klen); + +- rc = smbd_post_send_iter(info, &iter, &remaining_data_length); ++ rc = smbd_post_send_full_iter(info, &iter, &remaining_data_length); + if (rc < 0) + break; + + if (iov_iter_count(&rqst->rq_iter) > 0) { + /* And then the data pages if there are any */ +- rc = smbd_post_send_iter(info, &rqst->rq_iter, +- &remaining_data_length); ++ rc = smbd_post_send_full_iter(info, &rqst->rq_iter, ++ &remaining_data_length); + if (rc < 0) + break; + } -- 2.47.2