nvmf/vfio-user: don't block DSM command in vfio-user

Previously we only process Read/Write/Flush IO commands, we should
not block the DSM command in vfio-user layer if the backend block
device can support it.

Change-Id: Ia6b90397adcc36015f331f011a5bdf3e3d6562d8
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6525
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Changpeng Liu 2021-02-23 20:22:52 +08:00 committed by Tomasz Zawadzki
parent d5bcc16d09
commit 17c5843d5a

View File

@ -2003,20 +2003,25 @@ get_nvmf_req(struct nvmf_vfio_user_qpair *qpair)
static int static int
get_nvmf_io_req_length(struct spdk_nvmf_request *req) get_nvmf_io_req_length(struct spdk_nvmf_request *req)
{ {
uint16_t nlb; uint16_t nlb, nr;
uint32_t nsid; uint32_t nsid;
struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
struct spdk_nvmf_ctrlr *ctrlr = req->qpair->ctrlr; struct spdk_nvmf_ctrlr *ctrlr = req->qpair->ctrlr;
struct spdk_nvmf_ns *ns; struct spdk_nvmf_ns *ns;
nsid = cmd->nsid; nsid = cmd->nsid;
nlb = (cmd->cdw12 & 0x0000ffffu) + 1;
ns = _nvmf_subsystem_get_ns(ctrlr->subsys, nsid); ns = _nvmf_subsystem_get_ns(ctrlr->subsys, nsid);
if (ns == NULL || ns->bdev == NULL) { if (ns == NULL || ns->bdev == NULL) {
SPDK_ERRLOG("unsuccessful query for nsid %u\n", cmd->nsid); SPDK_ERRLOG("unsuccessful query for nsid %u\n", cmd->nsid);
return -EINVAL; return -EINVAL;
} }
if (cmd->opc == SPDK_NVME_OPC_DATASET_MANAGEMENT) {
nr = cmd->cdw10_bits.dsm.nr + 1;
return nr * sizeof(struct spdk_nvme_dsm_range);
}
nlb = (cmd->cdw12 & 0x0000ffffu) + 1;
return nlb * spdk_bdev_get_block_size(ns->bdev); return nlb * spdk_bdev_get_block_size(ns->bdev);
} }
@ -2067,31 +2072,19 @@ static int
map_io_cmd_req(struct nvmf_vfio_user_ctrlr *ctrlr, struct spdk_nvmf_request *req) map_io_cmd_req(struct nvmf_vfio_user_ctrlr *ctrlr, struct spdk_nvmf_request *req)
{ {
int err = 0; int err = 0;
bool remap = true; struct spdk_nvme_cmd *cmd;
assert(ctrlr != NULL); assert(ctrlr != NULL);
assert(req != NULL); assert(req != NULL);
switch (req->cmd->nvme_cmd.opc) { cmd = &req->cmd->nvme_cmd;
case SPDK_NVME_OPC_FLUSH: req->xfer = spdk_nvme_opc_get_data_transfer(cmd->opc);
req->xfer = SPDK_NVME_DATA_NONE;
remap = false; if (spdk_unlikely(req->xfer == SPDK_NVME_DATA_NONE)) {
break; return 0;
case SPDK_NVME_OPC_READ:
req->xfer = SPDK_NVME_DATA_CONTROLLER_TO_HOST;
break;
case SPDK_NVME_OPC_WRITE:
req->xfer = SPDK_NVME_DATA_HOST_TO_CONTROLLER;
break;
default:
SPDK_ERRLOG("%s: SQ%d invalid I/O request type 0x%x\n",
ctrlr_id(ctrlr), req->qpair->qid,
req->cmd->nvme_cmd.opc);
return -EINVAL;
} }
req->data = NULL; /* SGL isn't supported now */
if (remap) {
assert(req->cmd->nvme_cmd.psdt == 0); assert(req->cmd->nvme_cmd.psdt == 0);
err = get_nvmf_io_req_length(req); err = get_nvmf_io_req_length(req);
if (err < 0) { if (err < 0) {
@ -2102,12 +2095,12 @@ map_io_cmd_req(struct nvmf_vfio_user_ctrlr *ctrlr, struct spdk_nvmf_request *req
err = vfio_user_map_prps(ctrlr, &req->cmd->nvme_cmd, req->iov, err = vfio_user_map_prps(ctrlr, &req->cmd->nvme_cmd, req->iov,
req->length); req->length);
if (err < 0) { if (err < 0) {
SPDK_ERRLOG("%s: failed to map PRP: %d\n", SPDK_ERRLOG("%s: failed to map PRP: %d\n", ctrlr_id(ctrlr), err);
ctrlr_id(ctrlr), err);
return -EFAULT; return -EFAULT;
} }
req->data = req->iov[0].iov_base;
req->iovcnt = err; req->iovcnt = err;
}
return 0; return 0;
} }