]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
smb: smbdirect: introduce smbdirect_connection_post_recv_io()
authorStefan Metzmacher <metze@samba.org>
Wed, 17 Sep 2025 07:13:25 +0000 (09:13 +0200)
committerSteve French <stfrench@microsoft.com>
Thu, 16 Apr 2026 02:58:19 +0000 (21:58 -0500)
This is basically a copy of smbd_post_recv() in the client and
smb_direct_post_recv() in the server.

The only difference is that this returns early if the connection
is already broken.

Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/common/smbdirect/smbdirect_connection.c

index 3b0cbbece44caf1ebc9faef241b1667053988eec..81b42eaec8b1bde6dc0f7b186bfae54333e284e3 100644 (file)
@@ -652,6 +652,48 @@ skip_free:
        wake_up(&sc->send_io.pending.dec_wait_queue);
 }
 
+__maybe_unused /* this is temporary while this file is included in others */
+static int smbdirect_connection_post_recv_io(struct smbdirect_recv_io *msg)
+{
+       struct smbdirect_socket *sc = msg->socket;
+       const struct smbdirect_socket_parameters *sp = &sc->parameters;
+       struct ib_recv_wr recv_wr = {
+               .wr_cqe = &msg->cqe,
+               .sg_list = &msg->sge,
+               .num_sge = 1,
+       };
+       int ret;
+
+       if (unlikely(sc->first_error))
+               return sc->first_error;
+
+       msg->sge.addr = ib_dma_map_single(sc->ib.dev,
+                                         msg->packet,
+                                         sp->max_recv_size,
+                                         DMA_FROM_DEVICE);
+       ret = ib_dma_mapping_error(sc->ib.dev, msg->sge.addr);
+       if (ret)
+               return ret;
+
+       msg->sge.length = sp->max_recv_size;
+       msg->sge.lkey = sc->ib.pd->local_dma_lkey;
+
+       ret = ib_post_recv(sc->ib.qp, &recv_wr, NULL);
+       if (ret) {
+               smbdirect_log_rdma_recv(sc, SMBDIRECT_LOG_ERR,
+                       "ib_post_recv failed ret=%d (%1pe)\n",
+                       ret, SMBDIRECT_DEBUG_ERR_PTR(ret));
+               ib_dma_unmap_single(sc->ib.dev,
+                                   msg->sge.addr,
+                                   msg->sge.length,
+                                   DMA_FROM_DEVICE);
+               msg->sge.length = 0;
+               smbdirect_socket_schedule_cleanup(sc, ret);
+       }
+
+       return ret;
+}
+
 static bool smbdirect_map_sges_single_page(struct smbdirect_map_sges *state,
                                           struct page *page, size_t off, size_t len)
 {