Commit 3e691b1d authored by Stefan Metzmacher's avatar Stefan Metzmacher Committed by Steve French
Browse files

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: default avatarStefan Metzmacher <metze@samba.org>
Acked-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 177368b9
Loading
Loading
Loading
Loading
+25 −19
Original line number Diff line number Diff line
@@ -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,13 +503,16 @@ 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:

	/* This is an internal error */
	return -EINVAL;
}
	return 0;
}

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) {