diff options
author | Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> | 2022-03-07 19:34:30 +0100 |
---|---|---|
committer | Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> | 2022-06-08 18:14:16 +0200 |
commit | baf9a8500e8914f180ede682c95a37266e1a4e37 (patch) | |
tree | 9add9a1c90f930af993cc99946b1a06d172b73cf /usr/src/uts/common | |
parent | 0a4ff7c07705facb2cf0991453d0a3e20cdc50ce (diff) | |
download | illumos-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.c | 86 | ||||
-rw-r--r-- | usr/src/uts/common/io/nvme/nvme_var.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/sys/nvme.h | 28 |
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 |