1);
}
-static int smb_direct_create_header(struct smbdirect_socket *sc,
- int size, int remaining_data_length,
- int new_credits,
- struct smbdirect_send_io **sendmsg_out)
-{
- struct smbdirect_socket_parameters *sp = &sc->parameters;
- struct smbdirect_send_io *sendmsg;
- struct smbdirect_data_transfer *packet;
- int header_length;
- int ret;
-
- sendmsg = smbdirect_connection_alloc_send_io(sc);
- if (IS_ERR(sendmsg))
- return PTR_ERR(sendmsg);
-
- /* Fill in the packet header */
- packet = (struct smbdirect_data_transfer *)sendmsg->packet;
- packet->credits_requested = cpu_to_le16(sp->send_credit_target);
- packet->credits_granted = cpu_to_le16(new_credits);
-
- packet->flags = 0;
- if (smbdirect_connection_request_keep_alive(sc))
- packet->flags |= cpu_to_le16(SMBDIRECT_FLAG_RESPONSE_REQUESTED);
-
- packet->reserved = 0;
- if (!size)
- packet->data_offset = 0;
- else
- packet->data_offset = cpu_to_le32(24);
- packet->data_length = cpu_to_le32(size);
- packet->remaining_data_length = cpu_to_le32(remaining_data_length);
- packet->padding = 0;
-
- ksmbd_debug(RDMA,
- "credits_requested=%d credits_granted=%d data_offset=%d data_length=%d remaining_data_length=%d\n",
- le16_to_cpu(packet->credits_requested),
- le16_to_cpu(packet->credits_granted),
- le32_to_cpu(packet->data_offset),
- le32_to_cpu(packet->data_length),
- le32_to_cpu(packet->remaining_data_length));
-
- /* Map the packet to DMA */
- header_length = sizeof(struct smbdirect_data_transfer);
- /* If this is a packet without payload, don't send padding */
- if (!size)
- header_length =
- offsetof(struct smbdirect_data_transfer, padding);
-
- sendmsg->sge[0].addr = ib_dma_map_single(sc->ib.dev,
- (void *)packet,
- header_length,
- DMA_TO_DEVICE);
- ret = ib_dma_mapping_error(sc->ib.dev, sendmsg->sge[0].addr);
- if (ret) {
- smbdirect_connection_free_send_io(sendmsg);
- return ret;
- }
-
- sendmsg->num_sge = 1;
- sendmsg->sge[0].length = header_length;
- sendmsg->sge[0].lkey = sc->ib.pd->local_dma_lkey;
-
- *sendmsg_out = sendmsg;
- return 0;
-}
-
static int post_sendmsg(struct smbdirect_socket *sc,
struct smbdirect_send_batch *send_ctx,
struct smbdirect_send_io *msg)
struct iov_iter *iter,
size_t *_remaining_data_length)
{
+ const struct smbdirect_socket_parameters *sp = &sc->parameters;
int ret;
struct smbdirect_send_io *msg;
+ struct smbdirect_data_transfer *packet;
+ size_t header_length;
u32 remaining_data_length = 0;
u32 data_length = 0;
struct smbdirect_send_batch _send_ctx;
u16 new_credits;
+ if (iter) {
+ header_length = sizeof(struct smbdirect_data_transfer);
+ } else {
+ /* If this is a packet without payload, don't send padding */
+ header_length = offsetof(struct smbdirect_data_transfer, padding);
+ }
+
if (!send_ctx) {
smb_direct_send_ctx_init(&_send_ctx, false, 0);
send_ctx = &_send_ctx;
remaining_data_length = *_remaining_data_length;
}
- ret = smb_direct_create_header(sc, data_length, remaining_data_length,
- new_credits, &msg);
+ msg = smbdirect_connection_alloc_send_io(sc);
+ if (IS_ERR(msg)) {
+ ret = PTR_ERR(msg);
+ goto alloc_failed;
+ }
+
+ /* Map the packet to DMA */
+ msg->sge[0].addr = ib_dma_map_single(sc->ib.dev,
+ msg->packet,
+ header_length,
+ DMA_TO_DEVICE);
+ ret = ib_dma_mapping_error(sc->ib.dev, msg->sge[0].addr);
if (ret)
- goto header_failed;
+ goto err;
+
+ msg->sge[0].length = header_length;
+ msg->sge[0].lkey = sc->ib.pd->local_dma_lkey;
+ msg->num_sge = 1;
if (iter) {
struct smbdirect_map_sges extract = {
msg->num_sge = extract.num_sge;
}
+ /* Fill in the packet header */
+ packet = (struct smbdirect_data_transfer *)msg->packet;
+ packet->credits_requested = cpu_to_le16(sp->send_credit_target);
+ new_credits = smbdirect_connection_grant_recv_credits(sc);
+ packet->credits_granted = cpu_to_le16(new_credits);
+
+ packet->flags = 0;
+ if (smbdirect_connection_request_keep_alive(sc))
+ packet->flags |= cpu_to_le16(SMBDIRECT_FLAG_RESPONSE_REQUESTED);
+
+ packet->reserved = 0;
+ if (!data_length)
+ packet->data_offset = 0;
+ else
+ packet->data_offset = cpu_to_le32(24);
+ packet->data_length = cpu_to_le32(data_length);
+ packet->remaining_data_length = cpu_to_le32(remaining_data_length);
+ packet->padding = 0;
+
+ ksmbd_debug(RDMA,
+ "credits_req=%u credits_granted=%u flags=0x%x ofs=%u len=%u remaining=%u\n",
+ le16_to_cpu(packet->credits_requested),
+ le16_to_cpu(packet->credits_granted),
+ le16_to_cpu(packet->flags),
+ le32_to_cpu(packet->data_offset),
+ le32_to_cpu(packet->data_length),
+ le32_to_cpu(packet->remaining_data_length));
+
ret = post_sendmsg(sc, send_ctx, msg);
if (ret)
goto err;
err:
smbdirect_connection_free_send_io(msg);
flush_failed:
-header_failed:
+alloc_failed:
atomic_inc(&sc->send_io.credits.count);
credit_failed:
atomic_inc(&sc->send_io.lcredits.count);