From a435e9eeee1400e911ca0fbbc7bd59be96ba547c Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Fri, 24 Jun 2016 16:24:55 -0700 Subject: [PATCH] nvmf: pass bb and in-capsule data to prep_data This fixes an oversight that allowed in-capsule data block SGLs to potentially refer to more than the received in-capsule data size. It also makes spdk_nvmf_request_prep_data() less dependent on the RDMA-specific rx_desc/tx_desc structures. Change-Id: I34d61aca4cf5ba033849673116d16ec90488dcd4 Signed-off-by: Daniel Verkamp --- lib/nvmf/conn.c | 7 ++++--- lib/nvmf/rdma.c | 2 -- lib/nvmf/rdma.h | 1 - lib/nvmf/request.c | 15 ++++++++------- lib/nvmf/request.h | 4 +++- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/lib/nvmf/conn.c b/lib/nvmf/conn.c index abed864d1..83990085e 100644 --- a/lib/nvmf/conn.c +++ b/lib/nvmf/conn.c @@ -476,8 +476,7 @@ static int nvmf_recv(struct spdk_nvmf_conn *conn, struct ibv_wc *wc) SPDK_ERRLOG("recv length less than capsule header\n"); goto recv_error; } - rx_desc->recv_bc = wc->byte_len; - SPDK_TRACELOG(SPDK_TRACE_NVMF, "recv byte count %x\n", rx_desc->recv_bc); + SPDK_TRACELOG(SPDK_TRACE_NVMF, "recv byte count 0x%x\n", wc->byte_len); /* get a response buffer */ if (STAILQ_EMPTY(&conn->rdma.qp_tx_desc)) { @@ -499,7 +498,9 @@ static int nvmf_recv(struct spdk_nvmf_conn *conn, struct ibv_wc *wc) nvmf_trace_command(cap_hdr, conn->type); - ret = spdk_nvmf_request_prep_data(req); + ret = spdk_nvmf_request_prep_data(req, + rx_desc->bb, wc->byte_len - sizeof(*cap_hdr), + rx_desc->bb, rx_desc->bb_sgl.length); if (ret < 0) { SPDK_ERRLOG("prep_data failed\n"); goto recv_error; diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index 6b37b1b7b..de546bc4d 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -401,8 +401,6 @@ nvmf_post_rdma_recv(struct spdk_nvmf_conn *conn, conn->sq_head < (conn->sq_depth - 1) ? (conn->sq_head++) : (conn->sq_head = 0); SPDK_TRACELOG(SPDK_TRACE_DEBUG, "sq_head %x, sq_depth %x\n", conn->sq_head, conn->sq_depth); - rx_desc->recv_bc = 0; /* clear previous recv byte count */ - wr.wr_id = (uintptr_t)rx_desc; wr.next = NULL; wr.sg_list = &rx_desc->recv_sgl; diff --git a/lib/nvmf/rdma.h b/lib/nvmf/rdma.h index a7c07962e..3f7ee74a8 100644 --- a/lib/nvmf/rdma.h +++ b/lib/nvmf/rdma.h @@ -67,7 +67,6 @@ struct nvme_qp_rx_desc { struct ibv_mr *bb_mr; uint8_t *bb; uint32_t bb_len; - uint32_t recv_bc; STAILQ_ENTRY(nvme_qp_rx_desc) link; }; diff --git a/lib/nvmf/request.c b/lib/nvmf/request.c index 574bd7fb7..ff45f8e27 100644 --- a/lib/nvmf/request.c +++ b/lib/nvmf/request.c @@ -654,10 +654,11 @@ nvmf_process_fabrics_command(struct nvmf_request *req) } int -spdk_nvmf_request_prep_data(struct nvmf_request *req) +spdk_nvmf_request_prep_data(struct nvmf_request *req, + void *in_cap_data, uint32_t in_cap_len, + void *bb, uint32_t bb_len) { struct nvme_qp_tx_desc *tx_desc = req->tx_desc; - struct nvme_qp_rx_desc *rx_desc = req->rx_desc; struct spdk_nvmf_conn *conn = tx_desc->conn; struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; enum spdk_nvme_data_transfer xfer; @@ -678,20 +679,20 @@ spdk_nvmf_request_prep_data(struct nvmf_request *req) SPDK_TRACELOG(SPDK_TRACE_RDMA, "Keyed data block: raddr 0x%" PRIx64 ", rkey 0x%x, length 0x%x\n", sgl->address, sgl->keyed.key, sgl->keyed.length); - if (sgl->keyed.length > rx_desc->bb_sgl.length) { + if (sgl->keyed.length > bb_len) { SPDK_ERRLOG("SGL length 0x%x exceeds BB length 0x%x\n", - sgl->keyed.length, rx_desc->bb_sgl.length); + sgl->keyed.length, bb_len); return -1; } - req->data = rx_desc->bb; + req->data = bb; req->remote_addr = sgl->address; req->rkey = sgl->keyed.key; req->length = sgl->keyed.length; } else if (sgl->generic.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK && sgl->unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_OFFSET) { uint64_t offset = sgl->address; - uint32_t max_len = rx_desc->bb_sgl.length; + uint32_t max_len = in_cap_len; SPDK_TRACELOG(SPDK_TRACE_RDMA, "In-capsule data: offset 0x%" PRIx64 ", length 0x%x\n", offset, sgl->unkeyed.length); @@ -714,7 +715,7 @@ spdk_nvmf_request_prep_data(struct nvmf_request *req) return -1; } - req->data = rx_desc->bb + offset; + req->data = in_cap_data + offset; req->length = sgl->unkeyed.length; } else { SPDK_ERRLOG("Invalid NVMf I/O Command SGL: Type 0x%x, Subtype 0x%x\n", diff --git a/lib/nvmf/request.h b/lib/nvmf/request.h index c883e1048..1bcf1c900 100644 --- a/lib/nvmf/request.h +++ b/lib/nvmf/request.h @@ -74,7 +74,9 @@ struct nvmf_request { }; int -spdk_nvmf_request_prep_data(struct nvmf_request *req); +spdk_nvmf_request_prep_data(struct nvmf_request *req, + void *in_cap_data, uint32_t in_cap_len, + void *bb, uint32_t bb_len); int spdk_nvmf_request_exec(struct nvmf_request *req);