From ddb680ebab4cb97d2ed4abd9d5c9fb6ae26fb6ca Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Thu, 20 Jun 2019 09:56:58 +0900 Subject: [PATCH] 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 Change-Id: I796c20607c7b64a8be85da5131c5ea95ffd9f8e4 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/458713 Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Paul Luse --- lib/nvmf/ctrlr.c | 50 +++++++++++++++++++ lib/nvmf/nvmf_internal.h | 2 + test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c | 70 ++++++++++++++++++++++++++- 3 files changed, 121 insertions(+), 1 deletion(-) diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index d786a3677..79be86898 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -2615,3 +2615,53 @@ spdk_nvmf_request_exec(struct spdk_nvmf_request *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); +} diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index 91f957712..c74bbfbd8 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -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_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, uint32_t iovcnt, uint64_t offset, uint32_t length); diff --git a/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c b/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c index 5f867fabc..be408c94a 100644 --- a/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c +++ b/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c @@ -163,6 +163,11 @@ DEFINE_STUB(spdk_nvmf_transport_req_complete, 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 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); } +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) { 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", test_reservation_exclusive_access_regs_only_and_all_regs) == NULL || 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(); return CU_get_error();