diff --git a/lib/nvme/nvme_tcp.c b/lib/nvme/nvme_tcp.c index 266045afb..578731bd6 100644 --- a/lib/nvme/nvme_tcp.c +++ b/lib/nvme/nvme_tcp.c @@ -970,7 +970,7 @@ nvme_tcp_c2h_data_payload_handle(struct nvme_tcp_qpair *tqpair, tcp_req->datao += pdu->data_len; flags = c2h_data->common.flags; - if (flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS) { + if (flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU) { if (tcp_req->datao == tcp_req->req->payload_size) { tcp_req->rsp.status.p = 0; } else { @@ -979,10 +979,11 @@ nvme_tcp_c2h_data_payload_handle(struct nvme_tcp_qpair *tqpair, tcp_req->rsp.cid = tcp_req->cid; tcp_req->rsp.sqid = tqpair->qpair.id; - tcp_req->ordering.bits.data_recv = 1; - - if (nvme_tcp_req_complete_safe(tcp_req)) { - (*reaped)++; + if (flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS) { + tcp_req->ordering.bits.data_recv = 1; + if (nvme_tcp_req_complete_safe(tcp_req)) { + (*reaped)++; + } } } } @@ -1292,6 +1293,7 @@ nvme_tcp_c2h_data_hdr_handle(struct nvme_tcp_qpair *tqpair, struct nvme_tcp_pdu struct spdk_nvme_tcp_c2h_data_hdr *c2h_data = &pdu->hdr.c2h_data; uint32_t error_offset = 0; enum spdk_nvme_tcp_term_req_fes fes; + int flags = c2h_data->common.flags; SPDK_DEBUGLOG(nvme, "enter\n"); SPDK_DEBUGLOG(nvme, "c2h_data info on tqpair(%p): datao=%u, datal=%u, cccid=%d\n", @@ -1308,6 +1310,14 @@ nvme_tcp_c2h_data_hdr_handle(struct nvme_tcp_qpair *tqpair, struct nvme_tcp_pdu SPDK_DEBUGLOG(nvme, "tcp_req(%p) on tqpair(%p): datao=%u, payload_size=%u\n", tcp_req, tqpair, tcp_req->datao, tcp_req->req->payload_size); + if (spdk_unlikely((flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS) && + !(flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU))) { + SPDK_ERRLOG("Invalid flag flags=%d in c2h_data=%p\n", flags, c2h_data); + fes = SPDK_NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD; + error_offset = offsetof(struct spdk_nvme_tcp_c2h_data_hdr, common); + goto end; + } + if (c2h_data->datal > tcp_req->req->payload_size) { SPDK_ERRLOG("Invalid datal for tcp_req(%p), datal(%u) exceeds payload_size(%u)\n", tcp_req, c2h_data->datal, tcp_req->req->payload_size); diff --git a/test/unit/lib/nvme/nvme_tcp.c/nvme_tcp_ut.c b/test/unit/lib/nvme/nvme_tcp.c/nvme_tcp_ut.c index 448d65014..6b9042e54 100644 --- a/test/unit/lib/nvme/nvme_tcp.c/nvme_tcp_ut.c +++ b/test/unit/lib/nvme/nvme_tcp.c/nvme_tcp_ut.c @@ -1157,7 +1157,8 @@ test_nvme_tcp_c2h_payload_handle(void) TAILQ_INIT(&tcp_req.tqpair->outstanding_reqs); pdu.req = &tcp_req; - pdu.hdr.c2h_data.common.flags = SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS; + pdu.hdr.c2h_data.common.flags = SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS | + SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU; pdu.data_len = 1024; tqpair.qpair.id = 1; @@ -1303,7 +1304,8 @@ test_nvme_tcp_pdu_payload_handle(void) tqpair.qpair.id = 1; recv_pdu.ddgst_enable = false; recv_pdu.req = &tcp_req; - recv_pdu.hdr.c2h_data.common.flags = SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS; + recv_pdu.hdr.c2h_data.common.flags = SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS | + SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU; recv_pdu.data_len = 1024; tcp_req.ordering.bits.data_recv = 0; tcp_req.req->cb_fn = ut_nvme_complete_request;