summaryrefslogtreecommitdiff
path: root/usr/src/uts/common
diff options
context:
space:
mode:
authorHans Rosenfeld <rosenfeld@grumpf.hope-2000.org>2022-03-07 19:34:30 +0100
committerHans Rosenfeld <rosenfeld@grumpf.hope-2000.org>2022-06-08 18:14:16 +0200
commitbaf9a8500e8914f180ede682c95a37266e1a4e37 (patch)
tree9add9a1c90f930af993cc99946b1a06d172b73cf /usr/src/uts/common
parent0a4ff7c07705facb2cf0991453d0a3e20cdc50ce (diff)
downloadillumos-joyent-baf9a8500e8914f180ede682c95a37266e1a4e37.tar.gz
14550 nvme_is_ignored_ns() needs less confusion
14709 nvmeadm list should be able to distinguish between inactive and ignored namespaces Reviewed by: Andrew Giles <agiles@tintri.com> Reviewed by: Guy Morrogh <gmorrogh@tintri.com> Reviewed by: Robert Mustacchi <rm+illumos@fingolfin.org> Approved by: Gordon Ross <gordon.w.ross@gmail.com>
Diffstat (limited to 'usr/src/uts/common')
-rw-r--r--usr/src/uts/common/io/nvme/nvme.c86
-rw-r--r--usr/src/uts/common/io/nvme/nvme_var.h2
-rw-r--r--usr/src/uts/common/sys/nvme.h28
3 files changed, 105 insertions, 11 deletions
diff --git a/usr/src/uts/common/io/nvme/nvme.c b/usr/src/uts/common/io/nvme/nvme.c
index e65a7a4139..a59564544f 100644
--- a/usr/src/uts/common/io/nvme/nvme.c
+++ b/usr/src/uts/common/io/nvme/nvme.c
@@ -2923,6 +2923,44 @@ nvme_prepare_devid(nvme_t *nvme, uint32_t nsid)
nvme->n_idctl->id_vid, model, serial, nsid);
}
+static boolean_t
+nvme_allocated_ns(nvme_namespace_t *ns)
+{
+ nvme_t *nvme = ns->ns_nvme;
+
+ ASSERT(MUTEX_HELD(&nvme->n_mgmt_mutex));
+
+ /*
+ * Since we don't know any better, we assume all namespaces to be
+ * allocated.
+ */
+ return (B_TRUE);
+}
+
+static boolean_t
+nvme_active_ns(nvme_namespace_t *ns)
+{
+ nvme_t *nvme = ns->ns_nvme;
+ boolean_t ret = B_FALSE;
+ uint64_t *ptr;
+
+ ASSERT(MUTEX_HELD(&nvme->n_mgmt_mutex));
+
+ /*
+ * Check whether the IDENTIFY NAMESPACE data is zero-filled.
+ */
+ for (ptr = (uint64_t *)ns->ns_idns;
+ ptr != (uint64_t *)(ns->ns_idns + 1);
+ ptr++) {
+ if (*ptr != 0) {
+ ret = B_TRUE;
+ break;
+ }
+ }
+
+ return (ret);
+}
+
static int
nvme_init_ns(nvme_t *nvme, int nsid)
{
@@ -2946,6 +2984,12 @@ nvme_init_ns(nvme_t *nvme, int nsid)
ns->ns_idns = idns;
ns->ns_id = nsid;
+
+ was_ignored = ns->ns_ignore;
+
+ ns->ns_allocated = nvme_allocated_ns(ns);
+ ns->ns_active = nvme_active_ns(ns);
+
ns->ns_block_count = idns->id_nsize;
ns->ns_block_size =
1 << idns->id_lbaf[idns->id_flbas.lba_format].lbaf_lbads;
@@ -3410,7 +3454,7 @@ nvme_init(nvme_t *nvme)
nvme->n_progress_supported = B_TRUE;
/*
- * Identify Namespaces
+ * Get number of supported namespaces and allocate namespace array.
*/
nvme->n_namespace_count = nvme->n_idctl->id_nn;
@@ -4884,6 +4928,9 @@ nvme_ioctl_get_logpage(nvme_t *nvme, int nsid, nvme_ioctl_t *nioc,
if ((mode & FREAD) == 0)
return (EPERM);
+ if (nsid > 0 && !NVME_NSID2NS(nvme, nsid)->ns_active)
+ return (EINVAL);
+
switch (nioc->n_arg) {
case NVME_LOGPAGE_ERROR:
if (nsid != 0)
@@ -4949,6 +4996,9 @@ nvme_ioctl_get_features(nvme_t *nvme, int nsid, nvme_ioctl_t *nioc,
if ((mode & FREAD) == 0)
return (EPERM);
+ if (nsid > 0 && !NVME_NSID2NS(nvme, nsid)->ns_active)
+ return (EINVAL);
+
if ((nioc->n_arg >> 32) > 0xff)
return (EINVAL);
@@ -5099,8 +5149,12 @@ nvme_ioctl_format(nvme_t *nvme, int nsid, nvme_ioctl_t *nioc, int mode,
if (nm->nm_oexcl != curthread)
return (EACCES);
- if (nsid != 0 && NVME_NSID2NS(nvme, nsid)->ns_attached)
- return (EBUSY);
+ if (nsid != 0) {
+ if (NVME_NSID2NS(nvme, nsid)->ns_attached)
+ return (EBUSY);
+ else if (!NVME_NSID2NS(nvme, nsid)->ns_active)
+ return (EINVAL);
+ }
frmt.r = nioc->n_arg & 0xffffffff;
@@ -5597,10 +5651,11 @@ out:
}
static int
-nvme_ioctl_is_ignored_ns(nvme_t *nvme, int nsid, nvme_ioctl_t *nioc, int mode,
+nvme_ioctl_ns_state(nvme_t *nvme, int nsid, nvme_ioctl_t *nioc, int mode,
cred_t *cred_p)
{
_NOTE(ARGUNUSED(cred_p));
+ nvme_namespace_t *ns = NVME_NSID2NS(nvme, nsid);
if ((mode & FREAD) == 0)
return (EPERM);
@@ -5608,10 +5663,23 @@ nvme_ioctl_is_ignored_ns(nvme_t *nvme, int nsid, nvme_ioctl_t *nioc, int mode,
if (nsid == 0)
return (EINVAL);
- if (NVME_NSID2NS(nvme, nsid)->ns_ignore)
- nioc->n_arg = 1;
- else
- nioc->n_arg = 0;
+ nioc->n_arg = 0;
+
+ mutex_enter(&nvme->n_mgmt_mutex);
+
+ if (ns->ns_allocated)
+ nioc->n_arg |= NVME_NS_STATE_ALLOCATED;
+
+ if (ns->ns_active)
+ nioc->n_arg |= NVME_NS_STATE_ACTIVE;
+
+ if (ns->ns_attached)
+ nioc->n_arg |= NVME_NS_STATE_ATTACHED;
+
+ if (ns->ns_ignore)
+ nioc->n_arg |= NVME_NS_STATE_IGNORED;
+
+ mutex_exit(&nvme->n_mgmt_mutex);
return (0);
}
@@ -5644,7 +5712,7 @@ nvme_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p,
nvme_ioctl_firmware_download,
nvme_ioctl_firmware_commit,
nvme_ioctl_passthru,
- nvme_ioctl_is_ignored_ns
+ nvme_ioctl_ns_state
};
if (nvme == NULL)
diff --git a/usr/src/uts/common/io/nvme/nvme_var.h b/usr/src/uts/common/io/nvme/nvme_var.h
index 0266f193dc..10cc529fd9 100644
--- a/usr/src/uts/common/io/nvme/nvme_var.h
+++ b/usr/src/uts/common/io/nvme/nvme_var.h
@@ -287,6 +287,8 @@ struct nvme_namespace {
size_t ns_block_size;
size_t ns_best_block_size;
+ boolean_t ns_allocated;
+ boolean_t ns_active;
boolean_t ns_ignore;
boolean_t ns_attached;
diff --git a/usr/src/uts/common/sys/nvme.h b/usr/src/uts/common/sys/nvme.h
index 9e154131b1..04f39057e2 100644
--- a/usr/src/uts/common/sys/nvme.h
+++ b/usr/src/uts/common/sys/nvme.h
@@ -54,8 +54,8 @@ extern "C" {
#define NVME_IOC_FIRMWARE_DOWNLOAD (NVME_IOC | 11)
#define NVME_IOC_FIRMWARE_COMMIT (NVME_IOC | 12)
#define NVME_IOC_PASSTHRU (NVME_IOC | 13)
-#define NVME_IOC_IS_IGNORED_NS (NVME_IOC | 14)
-#define NVME_IOC_MAX NVME_IOC_IS_IGNORED_NS
+#define NVME_IOC_NS_STATE (NVME_IOC | 14)
+#define NVME_IOC_MAX NVME_IOC_NS_STATE
#define IS_NVME_IOC(x) ((x) > NVME_IOC && (x) <= NVME_IOC_MAX)
#define NVME_IOC_CMD(x) ((x) & 0xff)
@@ -1029,6 +1029,30 @@ typedef struct {
} nvme_passthru_cmd32_t;
#endif
+/*
+ * NVME namespace state flags for NVME_IOC_NS_STATE ioctl
+ *
+ * The values are defined entirely by the driver. Some states correspond to
+ * namespace states described by the NVMe specification r1.3 section 6.1, others
+ * are specific to the implementation of this driver.
+ *
+ * The states are as follows:
+ * - ALLOCATED: the namespace exists in the controller as per the NVMe spec
+ * - ACTIVE: the namespace exists and is attached to this controller as per the
+ * NVMe spec. Any namespace that is ACTIVE is also ALLOCATED. This must not be
+ * confused with the ATTACHED state.
+ * - ATTACHED: the driver has attached a blkdev(4D) instance to this namespace.
+ * This state can be changed by userspace with the ioctls NVME_IOC_ATTACH and
+ * NVME_IOC_DETACH. A namespace can only be ATTACHED when it is not IGNORED.
+ * - IGNORED: the driver ignores this namespace, it never attaches a blkdev(4D).
+ * Namespaces are IGNORED when they are not ACTIVE, or if they are ACTIVE but
+ * have certain properties that the driver cannot handle.
+ */
+#define NVME_NS_STATE_ALLOCATED 0x1
+#define NVME_NS_STATE_ACTIVE 0x2
+#define NVME_NS_STATE_ATTACHED 0x4
+#define NVME_NS_STATE_IGNORED 0x8
+
#ifdef __cplusplus
}
#endif