nvmf: Move nvmf_request_prep_data into rdma.c
This is an RDMA-specific operation, so hide it inside the transport-specific layer. Change-Id: Iaa097e8dde78d820547b3a39e9717c992581340b Signed-off-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
9d9dc8452c
commit
2625cf4261
102
lib/nvmf/rdma.c
102
lib/nvmf/rdma.c
@ -724,6 +724,108 @@ static const char *CM_EVENT_STR[] = {
|
|||||||
};
|
};
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
static int
|
||||||
|
spdk_nvmf_request_prep_data(struct spdk_nvmf_request *req,
|
||||||
|
void *in_cap_data, uint32_t in_cap_len,
|
||||||
|
void *bb, uint32_t bb_len)
|
||||||
|
{
|
||||||
|
struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
|
||||||
|
struct spdk_nvme_cpl *rsp = &req->rsp->nvme_cpl;
|
||||||
|
enum spdk_nvme_data_transfer xfer;
|
||||||
|
|
||||||
|
req->length = 0;
|
||||||
|
req->xfer = SPDK_NVME_DATA_NONE;
|
||||||
|
req->data = NULL;
|
||||||
|
|
||||||
|
if (cmd->opc == SPDK_NVME_OPC_FABRIC) {
|
||||||
|
xfer = spdk_nvme_opc_get_data_transfer(req->cmd->nvmf_cmd.fctype);
|
||||||
|
} else {
|
||||||
|
xfer = spdk_nvme_opc_get_data_transfer(cmd->opc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xfer != SPDK_NVME_DATA_NONE) {
|
||||||
|
struct spdk_nvme_sgl_descriptor *sgl = (struct spdk_nvme_sgl_descriptor *)&cmd->dptr.sgl1;
|
||||||
|
|
||||||
|
if (sgl->generic.type == SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK &&
|
||||||
|
(sgl->keyed.subtype == SPDK_NVME_SGL_SUBTYPE_ADDRESS ||
|
||||||
|
sgl->keyed.subtype == SPDK_NVME_SGL_SUBTYPE_INVALIDATE_KEY)) {
|
||||||
|
if (sgl->keyed.length > bb_len) {
|
||||||
|
SPDK_ERRLOG("SGL length 0x%x exceeds BB length 0x%x\n",
|
||||||
|
sgl->keyed.length, bb_len);
|
||||||
|
rsp->status.sc = SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
req->data = bb;
|
||||||
|
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 = in_cap_len;
|
||||||
|
|
||||||
|
SPDK_TRACELOG(SPDK_TRACE_NVMF, "In-capsule data: offset 0x%" PRIx64 ", length 0x%x\n",
|
||||||
|
offset, sgl->unkeyed.length);
|
||||||
|
|
||||||
|
if (offset > max_len) {
|
||||||
|
SPDK_ERRLOG("In-capsule offset 0x%" PRIx64 " exceeds capsule length 0x%x\n",
|
||||||
|
offset, max_len);
|
||||||
|
rsp->status.sc = SPDK_NVME_SC_INVALID_SGL_OFFSET;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
max_len -= (uint32_t)offset;
|
||||||
|
|
||||||
|
if (sgl->unkeyed.length > max_len) {
|
||||||
|
SPDK_ERRLOG("In-capsule data length 0x%x exceeds capsule length 0x%x\n",
|
||||||
|
sgl->unkeyed.length, max_len);
|
||||||
|
rsp->status.sc = SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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",
|
||||||
|
sgl->generic.type, sgl->generic.subtype);
|
||||||
|
rsp->status.sc = SPDK_NVME_SC_SGL_DESCRIPTOR_TYPE_INVALID;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->length == 0) {
|
||||||
|
xfer = SPDK_NVME_DATA_NONE;
|
||||||
|
req->data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
req->xfer = xfer;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For any I/O that requires data to be
|
||||||
|
* pulled into target BB before processing by
|
||||||
|
* the backend NVMe device
|
||||||
|
*/
|
||||||
|
if (xfer == SPDK_NVME_DATA_HOST_TO_CONTROLLER) {
|
||||||
|
if (sgl->generic.type == SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK) {
|
||||||
|
SPDK_TRACELOG(SPDK_TRACE_NVMF, "Initiating Host to Controller data transfer\n");
|
||||||
|
/* Wait for transfer to complete before executing command. */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xfer == SPDK_NVME_DATA_NONE) {
|
||||||
|
SPDK_TRACELOG(SPDK_TRACE_NVMF, "No data to transfer\n");
|
||||||
|
assert(req->data == NULL);
|
||||||
|
assert(req->length == 0);
|
||||||
|
} else {
|
||||||
|
assert(req->data != NULL);
|
||||||
|
assert(req->length != 0);
|
||||||
|
SPDK_TRACELOG(SPDK_TRACE_NVMF, "%s data ready\n",
|
||||||
|
xfer == SPDK_NVME_DATA_HOST_TO_CONTROLLER ? "Host to Controller" :
|
||||||
|
"Controller to Host");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nvmf_recv(struct spdk_nvmf_rdma_request *rdma_req, struct ibv_wc *wc)
|
nvmf_recv(struct spdk_nvmf_rdma_request *rdma_req, struct ibv_wc *wc)
|
||||||
{
|
{
|
||||||
|
@ -445,111 +445,6 @@ nvmf_trace_command(union nvmf_h2c_msg *h2c_msg, enum conn_type conn_type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
spdk_nvmf_request_prep_data(struct spdk_nvmf_request *req,
|
|
||||||
void *in_cap_data, uint32_t in_cap_len,
|
|
||||||
void *bb, uint32_t bb_len)
|
|
||||||
{
|
|
||||||
struct spdk_nvmf_conn *conn = req->conn;
|
|
||||||
struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
|
|
||||||
struct spdk_nvme_cpl *rsp = &req->rsp->nvme_cpl;
|
|
||||||
enum spdk_nvme_data_transfer xfer;
|
|
||||||
|
|
||||||
nvmf_trace_command(req->cmd, conn->type);
|
|
||||||
|
|
||||||
req->length = 0;
|
|
||||||
req->xfer = SPDK_NVME_DATA_NONE;
|
|
||||||
req->data = NULL;
|
|
||||||
|
|
||||||
if (cmd->opc == SPDK_NVME_OPC_FABRIC) {
|
|
||||||
xfer = spdk_nvme_opc_get_data_transfer(req->cmd->nvmf_cmd.fctype);
|
|
||||||
} else {
|
|
||||||
xfer = spdk_nvme_opc_get_data_transfer(cmd->opc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xfer != SPDK_NVME_DATA_NONE) {
|
|
||||||
struct spdk_nvme_sgl_descriptor *sgl = (struct spdk_nvme_sgl_descriptor *)&cmd->dptr.sgl1;
|
|
||||||
|
|
||||||
if (sgl->generic.type == SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK &&
|
|
||||||
(sgl->keyed.subtype == SPDK_NVME_SGL_SUBTYPE_ADDRESS ||
|
|
||||||
sgl->keyed.subtype == SPDK_NVME_SGL_SUBTYPE_INVALIDATE_KEY)) {
|
|
||||||
if (sgl->keyed.length > bb_len) {
|
|
||||||
SPDK_ERRLOG("SGL length 0x%x exceeds BB length 0x%x\n",
|
|
||||||
sgl->keyed.length, bb_len);
|
|
||||||
rsp->status.sc = SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
req->data = bb;
|
|
||||||
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 = in_cap_len;
|
|
||||||
|
|
||||||
SPDK_TRACELOG(SPDK_TRACE_NVMF, "In-capsule data: offset 0x%" PRIx64 ", length 0x%x\n",
|
|
||||||
offset, sgl->unkeyed.length);
|
|
||||||
|
|
||||||
if (offset > max_len) {
|
|
||||||
SPDK_ERRLOG("In-capsule offset 0x%" PRIx64 " exceeds capsule length 0x%x\n",
|
|
||||||
offset, max_len);
|
|
||||||
rsp->status.sc = SPDK_NVME_SC_INVALID_SGL_OFFSET;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
max_len -= (uint32_t)offset;
|
|
||||||
|
|
||||||
if (sgl->unkeyed.length > max_len) {
|
|
||||||
SPDK_ERRLOG("In-capsule data length 0x%x exceeds capsule length 0x%x\n",
|
|
||||||
sgl->unkeyed.length, max_len);
|
|
||||||
rsp->status.sc = SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
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",
|
|
||||||
sgl->generic.type, sgl->generic.subtype);
|
|
||||||
rsp->status.sc = SPDK_NVME_SC_SGL_DESCRIPTOR_TYPE_INVALID;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req->length == 0) {
|
|
||||||
xfer = SPDK_NVME_DATA_NONE;
|
|
||||||
req->data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
req->xfer = xfer;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For any I/O that requires data to be
|
|
||||||
* pulled into target BB before processing by
|
|
||||||
* the backend NVMe device
|
|
||||||
*/
|
|
||||||
if (xfer == SPDK_NVME_DATA_HOST_TO_CONTROLLER) {
|
|
||||||
if (sgl->generic.type == SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK) {
|
|
||||||
SPDK_TRACELOG(SPDK_TRACE_NVMF, "Initiating Host to Controller data transfer\n");
|
|
||||||
/* Wait for transfer to complete before executing command. */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xfer == SPDK_NVME_DATA_NONE) {
|
|
||||||
SPDK_TRACELOG(SPDK_TRACE_NVMF, "No data to transfer\n");
|
|
||||||
assert(req->data == NULL);
|
|
||||||
assert(req->length == 0);
|
|
||||||
} else {
|
|
||||||
assert(req->data != NULL);
|
|
||||||
assert(req->length != 0);
|
|
||||||
SPDK_TRACELOG(SPDK_TRACE_NVMF, "%s data ready\n",
|
|
||||||
xfer == SPDK_NVME_DATA_HOST_TO_CONTROLLER ? "Host to Controller" :
|
|
||||||
"Controller to Host");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
spdk_nvmf_request_exec(struct spdk_nvmf_request *req)
|
spdk_nvmf_request_exec(struct spdk_nvmf_request *req)
|
||||||
{
|
{
|
||||||
@ -558,6 +453,8 @@ spdk_nvmf_request_exec(struct spdk_nvmf_request *req)
|
|||||||
struct spdk_nvme_cpl *rsp = &req->rsp->nvme_cpl;
|
struct spdk_nvme_cpl *rsp = &req->rsp->nvme_cpl;
|
||||||
bool done;
|
bool done;
|
||||||
|
|
||||||
|
nvmf_trace_command(req->cmd, req->conn->type);
|
||||||
|
|
||||||
if (cmd->opc == SPDK_NVME_OPC_FABRIC) {
|
if (cmd->opc == SPDK_NVME_OPC_FABRIC) {
|
||||||
done = nvmf_process_fabrics_command(req);
|
done = nvmf_process_fabrics_command(req);
|
||||||
} else if (session == NULL || !session->vcprop.cc.bits.en) {
|
} else if (session == NULL || !session->vcprop.cc.bits.en) {
|
||||||
|
@ -65,11 +65,6 @@ struct spdk_nvmf_request {
|
|||||||
union nvmf_c2h_msg *rsp;
|
union nvmf_c2h_msg *rsp;
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
|
||||||
spdk_nvmf_request_prep_data(struct spdk_nvmf_request *req,
|
|
||||||
void *in_cap_data, uint32_t in_cap_len,
|
|
||||||
void *bb, uint32_t bb_len);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
spdk_nvmf_request_exec(struct spdk_nvmf_request *req);
|
spdk_nvmf_request_exec(struct spdk_nvmf_request *req);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user