diff --git a/lib/nvmf/tcp.c b/lib/nvmf/tcp.c index a5886cf826..b16ed22a4d 100644 --- a/lib/nvmf/tcp.c +++ b/lib/nvmf/tcp.c @@ -1509,8 +1509,6 @@ nvmf_tcp_pdu_c2h_data_complete(void *cb_arg) struct spdk_nvmf_tcp_req *tcp_req = cb_arg; struct spdk_nvmf_tcp_qpair *tqpair = SPDK_CONTAINEROF(tcp_req->req.qpair, struct spdk_nvmf_tcp_qpair, qpair); - struct spdk_nvmf_tcp_transport *ttransport = SPDK_CONTAINEROF( - tcp_req->req.qpair->transport, struct spdk_nvmf_tcp_transport, transport); assert(tqpair != NULL); @@ -1521,7 +1519,7 @@ nvmf_tcp_pdu_c2h_data_complete(void *cb_arg) return; } - if (ttransport->tcp_opts.c2h_success) { + if (tcp_req->pdu->hdr.c2h_data.common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS) { nvmf_tcp_request_free(tcp_req); } else { nvmf_tcp_req_pdu_fini(tcp_req); @@ -2272,7 +2270,9 @@ _nvmf_tcp_send_c2h_data(struct spdk_nvmf_tcp_qpair *tqpair, c2h_data->common.flags |= SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU; - if (ttransport->tcp_opts.c2h_success) { + /* Need to send the capsule response if response is not all 0 */ + if (ttransport->tcp_opts.c2h_success && + tcp_req->rsp.cdw0 == 0 && tcp_req->rsp.cdw1 == 0) { c2h_data->common.flags |= SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS; } diff --git a/test/unit/lib/nvmf/tcp.c/tcp_ut.c b/test/unit/lib/nvmf/tcp.c/tcp_ut.c index 4d6a0a5c29..b96f9e8546 100644 --- a/test/unit/lib/nvmf/tcp.c/tcp_ut.c +++ b/test/unit/lib/nvmf/tcp.c/tcp_ut.c @@ -552,6 +552,7 @@ test_nvmf_tcp_send_c2h_data(void) struct nvme_tcp_pdu pdu = {}; struct spdk_nvme_tcp_c2h_data_hdr *c2h_data; + ttransport.tcp_opts.c2h_success = true; thread = spdk_thread_create(NULL, NULL); SPDK_CU_ASSERT_FATAL(thread != NULL); spdk_set_thread(thread); @@ -583,6 +584,7 @@ test_nvmf_tcp_send_c2h_data(void) CU_ASSERT(c2h_data->datal = 300); CU_ASSERT(c2h_data->common.plen == sizeof(*c2h_data) + 300); CU_ASSERT(c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU); + CU_ASSERT(c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS); CU_ASSERT(pdu.data_iovcnt == 3); CU_ASSERT((uint64_t)pdu.data_iov[0].iov_base == 0xDEADBEEF); @@ -592,6 +594,28 @@ test_nvmf_tcp_send_c2h_data(void) CU_ASSERT((uint64_t)pdu.data_iov[2].iov_base == 0xC0FFEE); CU_ASSERT(pdu.data_iov[2].iov_len == 99); + tcp_req.pdu_in_use = false; + tcp_req.rsp.cdw0 = 1; + nvmf_tcp_send_c2h_data(&tqpair, &tcp_req); + + CU_ASSERT(c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU); + CU_ASSERT((c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS) == 0); + + ttransport.tcp_opts.c2h_success = false; + tcp_req.pdu_in_use = false; + tcp_req.rsp.cdw0 = 0; + nvmf_tcp_send_c2h_data(&tqpair, &tcp_req); + + CU_ASSERT(c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU); + CU_ASSERT((c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS) == 0); + + tcp_req.pdu_in_use = false; + tcp_req.rsp.cdw0 = 1; + nvmf_tcp_send_c2h_data(&tqpair, &tcp_req); + + CU_ASSERT(c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU); + CU_ASSERT((c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS) == 0); + spdk_thread_exit(thread); while (!spdk_thread_is_exited(thread)) { spdk_thread_poll(thread, 0, 0);