From 468c6c18bd919c77051f9c9ff25dfb20fee295ad Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Sat, 2 Mar 2019 21:33:22 -0500 Subject: [PATCH] nvmf: enable get log page with reservation notification page Reservation notification log page can be returned via the get log page command with correct page number, users can get zeored page buffer if the controller didn't have any reservation notification log. Change-Id: I99f5e4b8917a6919eb68359628efa1bead4b21b5 Signed-off-by: Changpeng Liu Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/439934 Tested-by: SPDK CI Jenkins Reviewed-by: Shuhei Matsumoto Reviewed-by: Jim Harris Reviewed-by: GangCao --- lib/nvmf/ctrlr.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index 0edf934d6..02458ffdf 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -1358,6 +1358,48 @@ spdk_nvmf_get_cmds_and_effects_log_page(void *buffer, } } +static void +spdk_nvmf_get_reservation_notification_log_page(struct spdk_nvmf_ctrlr *ctrlr, + void *data, uint64_t offset, uint32_t length) +{ + uint32_t unit_log_len, avail_log_len, next_pos, copy_len; + struct spdk_nvmf_reservation_log *log, *log_tmp; + uint8_t *buf = data; + + unit_log_len = sizeof(struct spdk_nvme_reservation_notification_log); + /* No available log, return 1 zeroed log page */ + if (!ctrlr->num_avail_log_pages) { + memset(buf, 0, spdk_min(length, unit_log_len)); + return; + } + + avail_log_len = ctrlr->num_avail_log_pages * unit_log_len; + if (offset >= avail_log_len) { + return; + } + + next_pos = copy_len = 0; + TAILQ_FOREACH_SAFE(log, &ctrlr->log_head, link, log_tmp) { + TAILQ_REMOVE(&ctrlr->log_head, log, link); + ctrlr->num_avail_log_pages--; + + next_pos += unit_log_len; + if (next_pos > offset) { + copy_len = spdk_min(next_pos - offset, length); + memcpy(buf, &log->log, copy_len); + length -= copy_len; + offset += copy_len; + buf += copy_len; + } + free(log); + + if (length == 0) { + break; + } + } + return; +} + static int spdk_nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req) { @@ -1422,6 +1464,9 @@ spdk_nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req) 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; + case SPDK_NVME_LOG_RESERVATION_NOTIFICATION: + spdk_nvmf_get_reservation_notification_log_page(ctrlr, req->data, offset, len); + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; default: goto invalid_log_page; }