Re: [[PATCH v1] 13/37] [CIFS] SMBD: Implement SMBD protocol negotiation

2017-08-13 Thread Christoph Hellwig
> + request = mempool_alloc(info->request_mempool, GFP_KERNEL);
> + if (!request)
> + return rc;

Here you do a mempool allocation to guarantee forward progress..

> + request->sge = kzalloc(sizeof(struct ib_sge), GFP_KERNEL);
> + if (!request->sge)
> + goto allocate_sge_failed;

... and here it's a plain malloc in the same path, which renders the
above useless.  Also I would just embedd the sge into the containing
structure to avoid a memory allocation.

> + request->info = info;
> +
> + packet = (struct smbd_negotiate_req *) request->packet;
> + packet->min_version = cpu_to_le16(0x100);
> + packet->max_version = cpu_to_le16(0x100);

Canyou add a constant for the version code?

> + packet->reserved = cpu_to_le16(0);

no need to byte swap 0 - you can always assign it directly.


[[PATCH v1] 13/37] [CIFS] SMBD: Implement SMBD protocol negotiation

2017-08-02 Thread Long Li
From: Long Li 

Now we have all the code in place to support SMBD protocol negotiation with SMB 
server. SMBD negotiation is defined in [MS-SMBD] 3.1.5. After negotiation, the 
client and server are connected through SMBD, and they can use SMBD to transfer 
data payloads.

Signed-off-by: Long Li 
---
 fs/cifs/cifsrdma.c | 208 +
 fs/cifs/cifsrdma.h |  29 
 2 files changed, 237 insertions(+)

diff --git a/fs/cifs/cifsrdma.c b/fs/cifs/cifsrdma.c
index ecbc832..aa3d1a5 100644
--- a/fs/cifs/cifsrdma.c
+++ b/fs/cifs/cifsrdma.c
@@ -222,6 +222,80 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc)
mempool_free(request, request->info->request_mempool);
 }
 
+static void dump_smbd_negotiate_resp(struct smbd_negotiate_resp *resp)
+{
+   log_rdma_event("resp message min_version %u max_version %u "
+ "negotiated_version %u credits_requested %u "
+ "credits_granted %u status %u max_readwrite_size %u "
+ "preferred_send_size %u max_receive_size %u "
+ "max_fragmented_size %u\n",
+   resp->min_version, resp->max_version, resp->negotiated_version,
+   resp->credits_requested, resp->credits_granted, resp->status,
+   resp->max_readwrite_size, resp->preferred_send_size,
+   resp->max_receive_size, resp->max_fragmented_size);
+}
+
+/* Process a negotiation response message, according to [MS-SMBD]3.1.5.7 */
+static bool process_negotiation_response(struct cifs_rdma_response *response, 
int packet_length)
+{
+   struct cifs_rdma_info *info = response->info;
+   struct smbd_negotiate_resp *packet =
+   (struct smbd_negotiate_resp *) response->packet;
+
+   if (packet_length < sizeof (struct smbd_negotiate_resp)) {
+   log_rdma_event("error: packet_length=%d\n", packet_length);
+   return false;
+   }
+
+   if (le16_to_cpu(packet->negotiated_version) != 0x100) {
+   log_rdma_event("error: negotiated_version=%x\n",
+   le16_to_cpu(packet->negotiated_version));
+   return false;
+   }
+   info->protocol = le16_to_cpu(packet->negotiated_version);
+
+   if (packet->credits_requested == 0) {
+   log_rdma_event("error: credits_requested==0\n");
+   return false;
+   }
+   atomic_set(&info->receive_credit_target,
+   le16_to_cpu(packet->credits_requested));
+
+   if (packet->credits_granted == 0) {
+   log_rdma_event("error: credits_granted==0\n");
+   return false;
+   }
+   atomic_set(&info->send_credits, le16_to_cpu(packet->credits_granted));
+
+   atomic_set(&info->receive_credits, 0);
+
+   if (le32_to_cpu(packet->preferred_send_size) > info->max_receive_size) {
+   log_rdma_event("error: preferred_send_size=%d\n",
+   le32_to_cpu(packet->preferred_send_size));
+   return false;
+   }
+   info->max_receive_size = le32_to_cpu(packet->preferred_send_size);
+
+   if (le32_to_cpu(packet->max_receive_size) < 128) {
+   log_rdma_event("error: max_receive_size=%d\n",
+   le32_to_cpu(packet->max_receive_size));
+   return false;
+   }
+   info->max_send_size = min_t(int, info->max_send_size,
+   le32_to_cpu(packet->max_receive_size));
+
+   if (le32_to_cpu(packet->max_fragmented_size) < 131072) {
+   log_rdma_event("error: max_fragmented_size=%d\n",
+   le32_to_cpu(packet->max_fragmented_size));
+   return false;
+   }
+   info->max_fragmented_send_size = 
le32_to_cpu(packet->max_fragmented_size);
+
+   info->max_readwrite_size = le32_to_cpu(packet->max_readwrite_size);
+
+   return true;
+}
+
 /* Called from softirq, when recv is done */
 static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
 {
@@ -248,6 +322,14 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
DMA_FROM_DEVICE);
 
switch(response->type) {
+   case SMBD_NEGOTIATE_RESP:
+   dump_smbd_negotiate_resp(
+   (struct smbd_negotiate_resp *) response->packet);
+   info->full_packet_received = true;
+   info->negotiate_done = process_negotiation_response(response, 
wc->byte_len);
+   complete(&info->negotiate_completion);
+   break;
+
case SMBD_TRANSFER_DATA:
data_transfer = (struct smbd_data_transfer *) response->packet;
atomic_dec(&info->receive_credits);
@@ -397,6 +479,85 @@ static int cifs_rdma_ia_open(
 }
 
 /*
+ * Send a negotiation request message to the peer
+ * The negotiation procedure is in [MS-SMBD] 3.1.5.2 and 3.1.5.3
+ * After negotiation, the transport is connected and ready for
+ * carrying upp