nvmf/rdma: Add utility for detecting transfer direction
This can probably be moved to the generic nvmf code in the future, since nothing about it is RDMA specific. Change-Id: I99103e174d99a619d36e519820a8a8a9b56473ac Signed-off-by: Ben Walker <benjamin.walker@intel.com> Reviewed-on: https://review.gerrithub.io/374538 Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
ea957ff3a6
commit
730750facf
@ -751,6 +751,62 @@ spdk_nvmf_rdma_mem_notify(void *cb_ctx, struct spdk_mem_map *map,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum spdk_nvme_data_transfer spdk_nvme_data_transfer_t;
|
||||||
|
|
||||||
|
static spdk_nvme_data_transfer_t
|
||||||
|
spdk_nvmf_rdma_request_get_xfer(struct spdk_nvmf_rdma_request *rdma_req)
|
||||||
|
{
|
||||||
|
enum spdk_nvme_data_transfer xfer;
|
||||||
|
struct spdk_nvme_cmd *cmd = &rdma_req->req.cmd->nvme_cmd;
|
||||||
|
struct spdk_nvme_sgl_descriptor *sgl = &cmd->dptr.sgl1;
|
||||||
|
|
||||||
|
/* Figure out data transfer direction */
|
||||||
|
if (cmd->opc == SPDK_NVME_OPC_FABRIC) {
|
||||||
|
xfer = spdk_nvme_opc_get_data_transfer(rdma_req->req.cmd->nvmf_cmd.fctype);
|
||||||
|
} else {
|
||||||
|
xfer = spdk_nvme_opc_get_data_transfer(cmd->opc);
|
||||||
|
|
||||||
|
/* Some admin commands are special cases */
|
||||||
|
if ((rdma_req->req.qpair->qid == 0) &&
|
||||||
|
((cmd->opc == SPDK_NVME_OPC_GET_FEATURES) ||
|
||||||
|
(cmd->opc == SPDK_NVME_OPC_SET_FEATURES))) {
|
||||||
|
switch (cmd->cdw10 & 0xff) {
|
||||||
|
case SPDK_NVME_FEAT_LBA_RANGE_TYPE:
|
||||||
|
case SPDK_NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION:
|
||||||
|
case SPDK_NVME_FEAT_HOST_IDENTIFIER:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
xfer = SPDK_NVME_DATA_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xfer == SPDK_NVME_DATA_NONE) {
|
||||||
|
return xfer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Even for commands that may transfer data, they could have specified 0 length.
|
||||||
|
* We want those to show up with xfer SPDK_NVME_DATA_NONE.
|
||||||
|
*/
|
||||||
|
switch (sgl->generic.type) {
|
||||||
|
case SPDK_NVME_SGL_TYPE_DATA_BLOCK:
|
||||||
|
case SPDK_NVME_SGL_TYPE_BIT_BUCKET:
|
||||||
|
case SPDK_NVME_SGL_TYPE_SEGMENT:
|
||||||
|
case SPDK_NVME_SGL_TYPE_LAST_SEGMENT:
|
||||||
|
if (sgl->unkeyed.length == 0) {
|
||||||
|
xfer = SPDK_NVME_DATA_NONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK:
|
||||||
|
if (sgl->keyed.length == 0) {
|
||||||
|
xfer = SPDK_NVME_DATA_NONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xfer;
|
||||||
|
}
|
||||||
|
|
||||||
static spdk_nvmf_request_prep_type
|
static spdk_nvmf_request_prep_type
|
||||||
spdk_nvmf_request_prep_data(struct spdk_nvmf_request *req)
|
spdk_nvmf_request_prep_data(struct spdk_nvmf_request *req)
|
||||||
{
|
{
|
||||||
@ -768,25 +824,7 @@ spdk_nvmf_request_prep_data(struct spdk_nvmf_request *req)
|
|||||||
req->length = 0;
|
req->length = 0;
|
||||||
req->data = NULL;
|
req->data = NULL;
|
||||||
|
|
||||||
if (cmd->opc == SPDK_NVME_OPC_FABRIC) {
|
req->xfer = spdk_nvmf_rdma_request_get_xfer(rdma_req);
|
||||||
req->xfer = spdk_nvme_opc_get_data_transfer(req->cmd->nvmf_cmd.fctype);
|
|
||||||
} else {
|
|
||||||
req->xfer = spdk_nvme_opc_get_data_transfer(cmd->opc);
|
|
||||||
if ((req->qpair->type == QPAIR_TYPE_AQ) &&
|
|
||||||
((cmd->opc == SPDK_NVME_OPC_GET_FEATURES) ||
|
|
||||||
(cmd->opc == SPDK_NVME_OPC_SET_FEATURES))) {
|
|
||||||
switch (cmd->cdw10 & 0xff) {
|
|
||||||
case SPDK_NVME_FEAT_LBA_RANGE_TYPE:
|
|
||||||
case SPDK_NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION:
|
|
||||||
case SPDK_NVME_FEAT_HOST_IDENTIFIER:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
req->xfer = SPDK_NVME_DATA_NONE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req->xfer == SPDK_NVME_DATA_NONE) {
|
if (req->xfer == SPDK_NVME_DATA_NONE) {
|
||||||
return SPDK_NVMF_REQUEST_PREP_READY;
|
return SPDK_NVMF_REQUEST_PREP_READY;
|
||||||
}
|
}
|
||||||
@ -805,11 +843,6 @@ spdk_nvmf_request_prep_data(struct spdk_nvmf_request *req)
|
|||||||
return SPDK_NVMF_REQUEST_PREP_ERROR;
|
return SPDK_NVMF_REQUEST_PREP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sgl->keyed.length == 0) {
|
|
||||||
req->xfer = SPDK_NVME_DATA_NONE;
|
|
||||||
return SPDK_NVMF_REQUEST_PREP_READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
req->length = sgl->keyed.length;
|
req->length = sgl->keyed.length;
|
||||||
req->data = spdk_mempool_get(rtransport->data_buf_pool);
|
req->data = spdk_mempool_get(rtransport->data_buf_pool);
|
||||||
if (!req->data) {
|
if (!req->data) {
|
||||||
@ -856,11 +889,6 @@ spdk_nvmf_request_prep_data(struct spdk_nvmf_request *req)
|
|||||||
return SPDK_NVMF_REQUEST_PREP_ERROR;
|
return SPDK_NVMF_REQUEST_PREP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sgl->unkeyed.length == 0) {
|
|
||||||
req->xfer = SPDK_NVME_DATA_NONE;
|
|
||||||
return SPDK_NVMF_REQUEST_PREP_READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
req->data = rdma_req->recv->buf + offset;
|
req->data = rdma_req->recv->buf + offset;
|
||||||
rdma_req->data_from_pool = false;
|
rdma_req->data_from_pool = false;
|
||||||
req->length = sgl->unkeyed.length;
|
req->length = sgl->unkeyed.length;
|
||||||
|
Loading…
Reference in New Issue
Block a user