diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 02f6da5f8..cd19f9adf 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -1065,9 +1065,38 @@ nvme_ctrlr_destruct_namespaces(struct spdk_nvme_ctrlr *ctrlr) } static int -nvme_ctrlr_construct_namespaces(struct spdk_nvme_ctrlr *ctrlr) +nvme_ctrlr_update_namespaces(struct spdk_nvme_ctrlr *ctrlr) { uint32_t i, nn = ctrlr->cdata.nn; + struct spdk_nvme_ns_data *nsdata; + + if (nvme_ctrlr_identify_active_ns(ctrlr)) { + return -1; + } + + for (i = 0; i < nn; i++) { + struct spdk_nvme_ns *ns = &ctrlr->ns[i]; + uint32_t nsid = i + 1; + nsdata = &ctrlr->nsdata[nsid - 1]; + + if ((nsdata->ncap == 0) && spdk_nvme_ctrlr_is_active_ns(ctrlr, nsid)) { + if (nvme_ns_construct(ns, nsid, ctrlr) != 0) { + continue; + } + } + + if (nsdata->ncap && !spdk_nvme_ctrlr_is_active_ns(ctrlr, nsid)) { + nvme_ns_destruct(ns); + } + } + + return 0; +} + +static int +nvme_ctrlr_construct_namespaces(struct spdk_nvme_ctrlr *ctrlr) +{ + uint32_t nn = ctrlr->cdata.nn; uint64_t phys_addr = 0; /* ctrlr->num_ns may be 0 (startup) or a different number of namespaces (reset), @@ -1096,19 +1125,9 @@ nvme_ctrlr_construct_namespaces(struct spdk_nvme_ctrlr *ctrlr) ctrlr->num_ns = nn; } - if (nvme_ctrlr_identify_active_ns(ctrlr)) { + if (nvme_ctrlr_update_namespaces(ctrlr)) { goto fail; } - - for (i = 0; i < nn; i++) { - struct spdk_nvme_ns *ns = &ctrlr->ns[i]; - uint32_t nsid = i + 1; - - if (nvme_ns_construct(ns, nsid, ctrlr) != 0) { - goto fail; - } - } - return 0; fail: @@ -1122,6 +1141,7 @@ nvme_ctrlr_async_event_cb(void *arg, const struct spdk_nvme_cpl *cpl) struct nvme_async_event_request *aer = arg; struct spdk_nvme_ctrlr *ctrlr = aer->ctrlr; struct spdk_nvme_ctrlr_process *active_proc; + union spdk_nvme_async_event_completion event; if (cpl->status.sc == SPDK_NVME_SC_ABORTED_SQ_DELETION) { /* @@ -1133,6 +1153,12 @@ nvme_ctrlr_async_event_cb(void *arg, const struct spdk_nvme_cpl *cpl) return; } + event.raw = cpl->cdw0; + if ((event.bits.async_event_type == SPDK_NVME_ASYNC_EVENT_TYPE_NOTICE) && + (event.bits.async_event_info == SPDK_NVME_ASYNC_EVENT_NS_ATTR_CHANGED)) { + nvme_ctrlr_update_namespaces(ctrlr); + } + active_proc = spdk_nvme_ctrlr_get_current_process(ctrlr); if (active_proc && active_proc->aer_cb_fn) { active_proc->aer_cb_fn(active_proc->aer_cb_arg, cpl); diff --git a/lib/nvme/nvme_ns.c b/lib/nvme/nvme_ns.c index 41cc13a74..e61b3700c 100644 --- a/lib/nvme/nvme_ns.c +++ b/lib/nvme/nvme_ns.c @@ -58,14 +58,7 @@ int nvme_ns_identify_update(struct spdk_nvme_ns *ns) &ns->ctrlr->ctrlr_lock)) { /* This can occur if the namespace is not active. Simply zero the * namespace data and continue. */ - memset(nsdata, 0, sizeof(*nsdata)); - ns->sector_size = 0; - ns->extended_lba_size = 0; - ns->md_size = 0; - ns->pi_type = 0; - ns->sectors_per_max_io = 0; - ns->sectors_per_stripe = 0; - ns->flags = 0; + nvme_ns_destruct(ns); return 0; } @@ -300,5 +293,19 @@ int nvme_ns_construct(struct spdk_nvme_ns *ns, uint32_t id, void nvme_ns_destruct(struct spdk_nvme_ns *ns) { + struct spdk_nvme_ns_data *nsdata; + if (!ns->id) { + return; + } + + nsdata = _nvme_ns_get_data(ns); + memset(nsdata, 0, sizeof(*nsdata)); + ns->sector_size = 0; + ns->extended_lba_size = 0; + ns->md_size = 0; + ns->pi_type = 0; + ns->sectors_per_max_io = 0; + ns->sectors_per_stripe = 0; + ns->flags = 0; }