From 26541489ef922a82cec9cbda412c9e0f1f20ac36 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Fri, 23 Mar 2018 14:20:04 -0700 Subject: [PATCH] nvmf: implement Get Log Page - Changed NS List Change-Id: I6219ace8deba0bfc3e3c7f6a4e00c0098584d5ee Signed-off-by: Daniel Verkamp Reviewed-on: https://review.gerrithub.io/405122 Reviewed-by: Changpeng Liu Reviewed-by: Shuhei Matsumoto Reviewed-by: Ben Walker Tested-by: SPDK Automated Test System --- lib/nvmf/ctrlr.c | 61 ++++++++++++++++--- lib/nvmf/nvmf_internal.h | 4 ++ lib/nvmf/subsystem.c | 2 +- .../ctrlr_discovery.c/ctrlr_discovery_ut.c | 11 ++-- test/unit/lib/nvmf/subsystem.c/subsystem_ut.c | 11 ++-- 5 files changed, 69 insertions(+), 20 deletions(-) diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index 53e4bdab5..7981a15ee 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -988,10 +988,59 @@ spdk_nvmf_get_firmware_slot_log_page(void *buffer, uint64_t offset, uint32_t len } } +void +spdk_nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid) +{ + uint16_t max_changes = SPDK_COUNTOF(ctrlr->changed_ns_list.ns_list); + uint16_t i; + bool found = false; + + for (i = 0; i < ctrlr->changed_ns_list_count; i++) { + if (ctrlr->changed_ns_list.ns_list[i] == nsid) { + /* nsid is already in the list */ + found = true; + break; + } + } + + if (!found) { + if (ctrlr->changed_ns_list_count == max_changes) { + /* Out of space - set first entry to FFFFFFFFh and zero-fill the rest. */ + ctrlr->changed_ns_list.ns_list[0] = 0xFFFFFFFFu; + for (i = 1; i < max_changes; i++) { + ctrlr->changed_ns_list.ns_list[i] = 0; + } + } else { + ctrlr->changed_ns_list.ns_list[ctrlr->changed_ns_list_count++] = nsid; + } + } + + spdk_nvmf_ctrlr_async_event_ns_notice(ctrlr); +} + +static void +spdk_nvmf_get_changed_ns_list_log_page(struct spdk_nvmf_ctrlr *ctrlr, + void *buffer, uint64_t offset, uint32_t length) +{ + size_t copy_length; + + if (offset < sizeof(ctrlr->changed_ns_list)) { + copy_length = spdk_min(length, sizeof(ctrlr->changed_ns_list) - offset); + if (copy_length) { + memcpy(buffer, (char *)&ctrlr->changed_ns_list + offset, copy_length); + } + } + + /* Clear log page each time it is read */ + ctrlr->changed_ns_list_count = 0; + memset(&ctrlr->changed_ns_list, 0, sizeof(ctrlr->changed_ns_list)); +} + static int spdk_nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req) { - struct spdk_nvmf_subsystem *subsystem = req->qpair->ctrlr->subsys; + struct spdk_nvmf_ctrlr *ctrlr = req->qpair->ctrlr; + struct spdk_nvmf_subsystem *subsystem = ctrlr->subsys; struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl; uint64_t offset, len; @@ -1048,6 +1097,9 @@ spdk_nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req) case SPDK_NVME_LOG_COMMAND_EFFECTS_LOG: spdk_nvmf_get_cmds_and_effects_log_page(req->data, offset, len); return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + case SPDK_NVME_LOG_CHANGED_NS_LIST: + spdk_nvmf_get_changed_ns_list_log_page(ctrlr, req->data, offset, len); + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; default: goto invalid_log_page; } @@ -1568,12 +1620,7 @@ spdk_nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr) event.bits.async_event_type = SPDK_NVME_ASYNC_EVENT_TYPE_NOTICE; event.bits.async_event_info = SPDK_NVME_ASYNC_EVENT_NS_ATTR_CHANGED; - /* Alternatively, host may request Changed Namespace List log(04h) - * to determine which namespaces have changed. While here, we - * set invalid log page identifier to indicate that host doesn't - * need to send such log page. - */ - event.bits.log_page_identifier = 0; + event.bits.log_page_identifier = SPDK_NVME_LOG_CHANGED_NS_LIST; /* If there is no outstanding AER request, queue the event. Then * if an AER is later submitted, this event can be sent as a diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index 4a98988db..5c5c7d332 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -189,6 +189,9 @@ struct spdk_nvmf_ctrlr { union spdk_nvme_async_event_completion notice_event; uint8_t hostid[16]; + uint16_t changed_ns_list_count; + struct spdk_nvme_ns_list changed_ns_list; + TAILQ_ENTRY(spdk_nvmf_ctrlr) link; }; @@ -252,6 +255,7 @@ int spdk_nvmf_ctrlr_process_admin_cmd(struct spdk_nvmf_request *req); int spdk_nvmf_ctrlr_process_io_cmd(struct spdk_nvmf_request *req); bool spdk_nvmf_ctrlr_dsm_supported(struct spdk_nvmf_ctrlr *ctrlr); bool spdk_nvmf_ctrlr_write_zeroes_supported(struct spdk_nvmf_ctrlr *ctrlr); +void spdk_nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid); int spdk_nvmf_bdev_ctrlr_identify_ns(struct spdk_nvmf_ns *ns, struct spdk_nvme_ns_data *nsdata); diff --git a/lib/nvmf/subsystem.c b/lib/nvmf/subsystem.c index ada009460..6e36d3eba 100644 --- a/lib/nvmf/subsystem.c +++ b/lib/nvmf/subsystem.c @@ -816,7 +816,7 @@ spdk_nvmf_subsystem_ns_changed(struct spdk_nvmf_subsystem *subsystem, uint32_t n struct spdk_nvmf_ctrlr *ctrlr; TAILQ_FOREACH(ctrlr, &subsystem->ctrlrs, link) { - spdk_nvmf_ctrlr_async_event_ns_notice(ctrlr); + spdk_nvmf_ctrlr_ns_changed(ctrlr, nsid); } } diff --git a/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c b/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c index 63bc0c093..7bc307444 100644 --- a/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c +++ b/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c @@ -153,6 +153,11 @@ spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1, return 0; } +void +spdk_nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid) +{ +} + void spdk_nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr) { @@ -186,12 +191,6 @@ spdk_nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group, return 0; } -int -spdk_nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr) -{ - return 0; -} - static void test_discovery_log(void) { diff --git a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c index c2a47a418..98e13f974 100644 --- a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c +++ b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c @@ -183,6 +183,11 @@ spdk_nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr) { } +void +spdk_nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid) +{ +} + int spdk_bdev_open(struct spdk_bdev *bdev, bool write, spdk_bdev_remove_cb_t remove_cb, void *remove_ctx, struct spdk_bdev_desc **desc) @@ -207,12 +212,6 @@ spdk_bdev_get_uuid(const struct spdk_bdev *bdev) return &bdev->uuid; } -int -spdk_nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr) -{ - return 0; -} - static void test_spdk_nvmf_subsystem_add_ns(void) {