nvmf: Add helper function to get DIF context from NVMf request

Add a helper function to get DIF context when the passed NVMf request
is for I/O queue, NVMe read, write, or compare command, and its NSID
is valid.

Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I796c20607c7b64a8be85da5131c5ea95ffd9f8e4
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/458713
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
This commit is contained in:
Shuhei Matsumoto 2019-06-20 09:56:58 +09:00 committed by Changpeng Liu
parent 9b04e29173
commit ddb680ebab
3 changed files with 121 additions and 1 deletions

View File

@ -2615,3 +2615,53 @@ spdk_nvmf_request_exec(struct spdk_nvmf_request *req)
spdk_nvmf_request_complete(req); spdk_nvmf_request_complete(req);
} }
} }
static bool
spdk_nvmf_ctrlr_get_dif_ctx(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_cmd *cmd,
struct spdk_dif_ctx *dif_ctx)
{
struct spdk_nvmf_ns *ns;
struct spdk_bdev *bdev;
if (ctrlr == NULL || cmd == NULL) {
return false;
}
ns = _spdk_nvmf_subsystem_get_ns(ctrlr->subsys, cmd->nsid);
if (ns == NULL || ns->bdev == NULL) {
return false;
}
bdev = ns->bdev;
switch (cmd->opc) {
case SPDK_NVME_OPC_READ:
case SPDK_NVME_OPC_WRITE:
case SPDK_NVME_OPC_COMPARE:
return spdk_nvmf_bdev_ctrlr_get_dif_ctx(bdev, cmd, dif_ctx);
default:
break;
}
return false;
}
bool
spdk_nvmf_request_get_dif_ctx(struct spdk_nvmf_request *req, struct spdk_dif_ctx *dif_ctx)
{
struct spdk_nvmf_qpair *qpair = req->qpair;
if (spdk_unlikely(qpair->state != SPDK_NVMF_QPAIR_ACTIVE)) {
return false;
}
if (spdk_unlikely(req->cmd->nvmf_cmd.opcode == SPDK_NVME_OPC_FABRIC)) {
return false;
}
if (spdk_unlikely(spdk_nvmf_qpair_is_admin_queue(qpair))) {
return false;
}
return spdk_nvmf_ctrlr_get_dif_ctx(qpair->ctrlr, &req->cmd->nvme_cmd, dif_ctx);
}

View File

@ -365,6 +365,8 @@ void spdk_nvmf_request_exec(struct spdk_nvmf_request *req);
int spdk_nvmf_request_free(struct spdk_nvmf_request *req); int spdk_nvmf_request_free(struct spdk_nvmf_request *req);
int spdk_nvmf_request_complete(struct spdk_nvmf_request *req); int spdk_nvmf_request_complete(struct spdk_nvmf_request *req);
bool spdk_nvmf_request_get_dif_ctx(struct spdk_nvmf_request *req, struct spdk_dif_ctx *dif_ctx);
void spdk_nvmf_get_discovery_log_page(struct spdk_nvmf_tgt *tgt, struct iovec *iov, void spdk_nvmf_get_discovery_log_page(struct spdk_nvmf_tgt *tgt, struct iovec *iov,
uint32_t iovcnt, uint64_t offset, uint32_t length); uint32_t iovcnt, uint64_t offset, uint32_t length);

View File

@ -163,6 +163,11 @@ DEFINE_STUB(spdk_nvmf_transport_req_complete,
DEFINE_STUB_V(spdk_nvmf_ns_reservation_request, (void *ctx)); DEFINE_STUB_V(spdk_nvmf_ns_reservation_request, (void *ctx));
DEFINE_STUB(spdk_nvmf_bdev_ctrlr_get_dif_ctx, bool,
(struct spdk_bdev *bdev, struct spdk_nvme_cmd *cmd,
struct spdk_dif_ctx *dif_ctx),
true);
int int
spdk_nvmf_qpair_disconnect(struct spdk_nvmf_qpair *qpair, nvmf_qpair_disconnect_cb cb_fn, void *ctx) spdk_nvmf_qpair_disconnect(struct spdk_nvmf_qpair *qpair, nvmf_qpair_disconnect_cb cb_fn, void *ctx)
{ {
@ -1154,6 +1159,68 @@ test_reservation_notification_log_page(void)
SPDK_CU_ASSERT_FATAL(ctrlr.num_avail_log_pages == 0); SPDK_CU_ASSERT_FATAL(ctrlr.num_avail_log_pages == 0);
} }
static void
test_get_dif_ctx(void)
{
struct spdk_nvmf_subsystem subsystem = {};
struct spdk_nvmf_request req = {};
struct spdk_nvmf_qpair qpair = {};
struct spdk_nvmf_ctrlr ctrlr = {};
struct spdk_nvmf_ns ns = {};
struct spdk_nvmf_ns *_ns = NULL;
struct spdk_bdev bdev = {};
union nvmf_h2c_msg cmd = {};
struct spdk_dif_ctx dif_ctx = {};
bool ret;
ctrlr.subsys = &subsystem;
qpair.ctrlr = &ctrlr;
req.qpair = &qpair;
req.cmd = &cmd;
ns.bdev = &bdev;
qpair.state = SPDK_NVMF_QPAIR_UNINITIALIZED;
ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx);
CU_ASSERT(ret == false);
qpair.state = SPDK_NVMF_QPAIR_ACTIVE;
cmd.nvmf_cmd.opcode = SPDK_NVME_OPC_FABRIC;
ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx);
CU_ASSERT(ret == false);
cmd.nvmf_cmd.opcode = SPDK_NVME_OPC_FLUSH;
ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx);
CU_ASSERT(ret == false);
qpair.qid = 1;
ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx);
CU_ASSERT(ret == false);
cmd.nvme_cmd.nsid = 1;
ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx);
CU_ASSERT(ret == false);
subsystem.max_nsid = 1;
subsystem.ns = &_ns;
subsystem.ns[0] = &ns;
ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx);
CU_ASSERT(ret == false);
cmd.nvmf_cmd.opcode = SPDK_NVME_OPC_WRITE;
ret = spdk_nvmf_request_get_dif_ctx(&req, &dif_ctx);
CU_ASSERT(ret == true);
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
CU_pSuite suite = NULL; CU_pSuite suite = NULL;
@ -1182,7 +1249,8 @@ int main(int argc, char **argv)
CU_add_test(suite, "reservation_exclusive_access_regs_only_and_all_regs", CU_add_test(suite, "reservation_exclusive_access_regs_only_and_all_regs",
test_reservation_exclusive_access_regs_only_and_all_regs) == NULL || test_reservation_exclusive_access_regs_only_and_all_regs) == NULL ||
CU_add_test(suite, "reservation_notification_log_page", CU_add_test(suite, "reservation_notification_log_page",
test_reservation_notification_log_page) == NULL test_reservation_notification_log_page) == NULL ||
CU_add_test(suite, "get_dif_ctx", test_get_dif_ctx) == NULL
) { ) {
CU_cleanup_registry(); CU_cleanup_registry();
return CU_get_error(); return CU_get_error();