smb: server: make use of smbdirect_socket->recv_io.expected

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>
This commit is contained in:
Stefan Metzmacher
2025-08-06 19:35:58 +02:00
committed by Steve French
parent 177368b992
commit 3e691b1d16

View 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;
return 0;
}
case SMBDIRECT_EXPECT_NEGOTIATE_REP:
/* client only */
break;
}
default:
return -EINVAL;
}
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) {