diff --git a/examples/nvme/identify/identify.c b/examples/nvme/identify/identify.c index 76a947c07..0f2218382 100644 --- a/examples/nvme/identify/identify.c +++ b/examples/nvme/identify/identify.c @@ -338,6 +338,11 @@ print_namespace(struct spdk_nvme_ns *ns) printf("\n"); } + if (!spdk_nvme_ns_is_active(ns)) { + printf("Inactive namespace ID\n\n"); + return; + } + printf("Deallocate: %s\n", (flags & SPDK_NVME_NS_DEALLOCATE_SUPPORTED) ? "Supported" : "Not Supported"); printf("Flush: %s\n", diff --git a/examples/nvme/perf/perf.c b/examples/nvme/perf/perf.c index b7bbad404..98a58ca5e 100644 --- a/examples/nvme/perf/perf.c +++ b/examples/nvme/perf/perf.c @@ -152,6 +152,13 @@ register_ns(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns) cdata = spdk_nvme_ctrlr_get_data(ctrlr); + if (!spdk_nvme_ns_is_active(ns)) { + printf("Controller %-20.20s (%-20.20s): Skipping inactive NS %u\n", + cdata->mn, cdata->sn, + spdk_nvme_ns_get_id(ns)); + return; + } + if (spdk_nvme_ns_get_size(ns) < g_io_size_bytes || spdk_nvme_ns_get_sector_size(ns) > g_io_size_bytes) { printf("WARNING: controller %-20.20s (%-20.20s) ns %u has invalid " diff --git a/include/spdk/nvme.h b/include/spdk/nvme.h index 226fc032c..567ac52fc 100644 --- a/include/spdk/nvme.h +++ b/include/spdk/nvme.h @@ -356,6 +356,13 @@ const struct spdk_nvme_ns_data *spdk_nvme_ns_get_data(struct spdk_nvme_ns *ns); */ uint32_t spdk_nvme_ns_get_id(struct spdk_nvme_ns *ns); +/** + * \brief Determine whether a namespace is active. + * + * Inactive namespaces cannot be the target of I/O commands. + */ +bool spdk_nvme_ns_is_active(struct spdk_nvme_ns *ns); + /** * \brief Get the maximum transfer size, in bytes, for an I/O sent to the given namespace. * diff --git a/lib/nvme/nvme_ns.c b/lib/nvme/nvme_ns.c index 3c2a53869..1b6c9005b 100644 --- a/lib/nvme/nvme_ns.c +++ b/lib/nvme/nvme_ns.c @@ -45,6 +45,19 @@ spdk_nvme_ns_get_id(struct spdk_nvme_ns *ns) return ns->id; } +bool +spdk_nvme_ns_is_active(struct spdk_nvme_ns *ns) +{ + const struct spdk_nvme_ns_data *nsdata = _nvme_ns_get_data(ns); + + /* + * According to the spec, Identify Namespace will return a zero-filled structure for + * inactive namespace IDs. + * Check NCAP since it must be nonzero for an active namespace. + */ + return nsdata->ncap != 0; +} + uint32_t spdk_nvme_ns_get_max_io_xfer_size(struct spdk_nvme_ns *ns) { diff --git a/test/lib/nvme/reset/reset.c b/test/lib/nvme/reset/reset.c index 01fb7e81c..d97267d0d 100644 --- a/test/lib/nvme/reset/reset.c +++ b/test/lib/nvme/reset/reset.c @@ -106,6 +106,11 @@ register_ns(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns) struct ns_entry *entry; const struct spdk_nvme_ctrlr_data *cdata; + if (!spdk_nvme_ns_is_active(ns)) { + printf("Skipping inactive NS %u\n", spdk_nvme_ns_get_id(ns)); + return; + } + entry = malloc(sizeof(struct ns_entry)); if (entry == NULL) { perror("ns_entry malloc");