]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
smb: server: make use of smbdirect_socket->recv_io.expected
authorStefan Metzmacher <metze@samba.org>
Wed, 6 Aug 2025 17:35:58 +0000 (19:35 +0200)
committerSteve French <stfrench@microsoft.com>
Sun, 28 Sep 2025 23:29:51 +0000 (18:29 -0500)
The expected incoming message type can be per connection.

Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
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/server/transport_rdma.c

index 499bb2c0bd79be13b1c221587c4bd201fe5aa42f..7892dd634c82e578a672925342084a7e4cd27201 100644 (file)
@@ -145,10 +145,6 @@ struct smb_direct_transport {
 #define KSMBD_TRANS(t) ((struct ksmbd_transport *)&((t)->transport))
 #define SMBD_TRANS(t)  ((struct smb_direct_transport *)container_of(t, \
                                struct smb_direct_transport, transport))
-enum {
-       SMB_DIRECT_MSG_NEGOTIATE_REQ = 0,
-       SMB_DIRECT_MSG_DATA_TRANSFER
-};
 
 static const struct ksmbd_transport_ops ksmbd_smb_direct_transport_ops;
 
@@ -172,7 +168,6 @@ struct smb_direct_sendmsg {
 struct smb_direct_recvmsg {
        struct smb_direct_transport     *transport;
        struct list_head        list;
-       int                     type;
        struct ib_sge           sge;
        struct ib_cqe           cqe;
        bool                    first_segment;
@@ -472,8 +467,10 @@ static void smb_direct_free_sendmsg(struct smb_direct_transport *t,
 
 static int smb_direct_check_recvmsg(struct smb_direct_recvmsg *recvmsg)
 {
-       switch (recvmsg->type) {
-       case SMB_DIRECT_MSG_DATA_TRANSFER: {
+       struct smbdirect_socket *sc = &recvmsg->transport->socket;
+
+       switch (sc->recv_io.expected) {
+       case SMBDIRECT_EXPECT_DATA_TRANSFER: {
                struct smbdirect_data_transfer *req =
                        (struct smbdirect_data_transfer *)recvmsg->packet;
                struct smb2_hdr *hdr = (struct smb2_hdr *)(recvmsg->packet
@@ -484,9 +481,9 @@ static int smb_direct_check_recvmsg(struct smb_direct_recvmsg *recvmsg)
                            le16_to_cpu(req->credits_requested),
                            req->data_length, req->remaining_data_length,
                            hdr->ProtocolId, hdr->Command);
-               break;
+               return 0;
        }
-       case SMB_DIRECT_MSG_NEGOTIATE_REQ: {
+       case SMBDIRECT_EXPECT_NEGOTIATE_REQ: {
                struct smbdirect_negotiate_req *req =
                        (struct smbdirect_negotiate_req *)recvmsg->packet;
                ksmbd_debug(RDMA,
@@ -506,12 +503,15 @@ static int smb_direct_check_recvmsg(struct smb_direct_recvmsg *recvmsg)
                                        128 * 1024)
                        return -ECONNABORTED;
 
-               break;
+               return 0;
        }
-       default:
-               return -EINVAL;
+       case SMBDIRECT_EXPECT_NEGOTIATE_REP:
+               /* client only */
+               break;
        }
-       return 0;
+
+       /* This is an internal error */
+       return -EINVAL;
 }
 
 static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
@@ -544,8 +544,8 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
        ib_dma_sync_single_for_cpu(wc->qp->device, recvmsg->sge.addr,
                                   recvmsg->sge.length, DMA_FROM_DEVICE);
 
-       switch (recvmsg->type) {
-       case SMB_DIRECT_MSG_NEGOTIATE_REQ:
+       switch (sc->recv_io.expected) {
+       case SMBDIRECT_EXPECT_NEGOTIATE_REQ:
                if (wc->byte_len < sizeof(struct smbdirect_negotiate_req)) {
                        put_recvmsg(t, recvmsg);
                        smb_direct_disconnect_rdma_connection(t);
@@ -557,7 +557,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
                enqueue_reassembly(t, recvmsg, 0);
                wake_up_interruptible(&t->wait_status);
                return;
-       case SMB_DIRECT_MSG_DATA_TRANSFER: {
+       case SMBDIRECT_EXPECT_DATA_TRANSFER: {
                struct smbdirect_data_transfer *data_transfer =
                        (struct smbdirect_data_transfer *)recvmsg->packet;
                u32 remaining_data_length, data_offset, data_length;
@@ -631,12 +631,15 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
 
                return;
        }
+       case SMBDIRECT_EXPECT_NEGOTIATE_REP:
+               /* client only */
+               break;
        }
 
        /*
         * This is an internal error!
         */
-       WARN_ON_ONCE(recvmsg->type != SMB_DIRECT_MSG_DATA_TRANSFER);
+       WARN_ON_ONCE(sc->recv_io.expected != SMBDIRECT_EXPECT_DATA_TRANSFER);
        put_recvmsg(t, recvmsg);
        smb_direct_disconnect_rdma_connection(t);
 }
@@ -824,7 +827,6 @@ static void smb_direct_post_recv_credits(struct work_struct *work)
                        if (!recvmsg)
                                break;
 
-                       recvmsg->type = SMB_DIRECT_MSG_DATA_TRANSFER;
                        recvmsg->first_segment = false;
 
                        ret = smb_direct_post_recv(t, recvmsg);
@@ -1675,6 +1677,8 @@ static int smb_direct_send_negotiate_response(struct smb_direct_transport *t,
                resp->max_receive_size = cpu_to_le32(sp->max_recv_size);
                resp->max_fragmented_size =
                                cpu_to_le32(sp->max_fragmented_recv_size);
+
+               sc->recv_io.expected = SMBDIRECT_EXPECT_DATA_TRANSFER;
        }
 
        sendmsg->sge[0].addr = ib_dma_map_single(sc->ib.dev,
@@ -1740,13 +1744,15 @@ static int smb_direct_accept_client(struct smb_direct_transport *t)
 
 static int smb_direct_prepare_negotiation(struct smb_direct_transport *t)
 {
+       struct smbdirect_socket *sc = &t->socket;
        int ret;
        struct smb_direct_recvmsg *recvmsg;
 
+       sc->recv_io.expected = SMBDIRECT_EXPECT_NEGOTIATE_REQ;
+
        recvmsg = get_free_recvmsg(t);
        if (!recvmsg)
                return -ENOMEM;
-       recvmsg->type = SMB_DIRECT_MSG_NEGOTIATE_REQ;
 
        ret = smb_direct_post_recv(t, recvmsg);
        if (ret) {