in host/tcp.c [707:776]
static int nvme_tcp_recv_data(struct nvme_tcp_queue *queue, struct sk_buff *skb,
unsigned int *offset, size_t *len)
{
struct nvme_tcp_data_pdu *pdu = (void *)queue->pdu;
struct request *rq =
nvme_cid_to_rq(nvme_tcp_tagset(queue), pdu->command_id);
struct nvme_tcp_request *req = blk_mq_rq_to_pdu(rq);
while (true) {
int recv_len, ret;
recv_len = min_t(size_t, *len, queue->data_remaining);
if (!recv_len)
break;
if (!iov_iter_count(&req->iter)) {
req->curr_bio = req->curr_bio->bi_next;
/*
* If we don`t have any bios it means that controller
* sent more data than we requested, hence error
*/
if (!req->curr_bio) {
dev_err(queue->ctrl->ctrl.device,
"queue %d no space in request %#x",
nvme_tcp_queue_id(queue), rq->tag);
nvme_tcp_init_recv_ctx(queue);
return -EIO;
}
nvme_tcp_init_iter(req, READ);
}
/* we can read only from what is left in this bio */
recv_len = min_t(size_t, recv_len,
iov_iter_count(&req->iter));
if (queue->data_digest)
ret = skb_copy_and_hash_datagram_iter(skb, *offset,
&req->iter, recv_len, queue->rcv_hash);
else
ret = skb_copy_datagram_iter(skb, *offset,
&req->iter, recv_len);
if (ret) {
dev_err(queue->ctrl->ctrl.device,
"queue %d failed to copy request %#x data",
nvme_tcp_queue_id(queue), rq->tag);
return ret;
}
*len -= recv_len;
*offset += recv_len;
queue->data_remaining -= recv_len;
}
if (!queue->data_remaining) {
if (queue->data_digest) {
nvme_tcp_ddgst_final(queue->rcv_hash, &queue->exp_ddgst);
queue->ddgst_remaining = NVME_TCP_DIGEST_LENGTH;
} else {
if (pdu->hdr.flags & NVME_TCP_F_DATA_SUCCESS) {
nvme_tcp_end_request(rq,
le16_to_cpu(req->status));
queue->nr_cqe++;
}
nvme_tcp_init_recv_ctx(queue);
}
}
return 0;
}