diff options
author | Keith Busch <keith.busch@intel.com> | 2015-12-22 12:10:45 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-12-22 12:10:45 -0500 |
commit | 2b9b6e86bca7209de02754fc84acf7ab3e78734e (patch) | |
tree | 1cd3492be06e261d610ef2d6eec5435ff03574a8 | |
parent | a0a3408ee614848c27b0d36c2fe490da3b387b8d (diff) |
NVMe: Export namespace attributes to sysfs
Exposes the NGUID, EUI-64, and NSID to sysfs entries under the disk's
kobject.
Signed-off-by: Keith Busch <keith.busch@intel.com>
Reviewed-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | drivers/nvme/host/core.c | 69 | ||||
-rw-r--r-- | drivers/nvme/host/nvme.h | 3 |
2 files changed, 70 insertions, 2 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index b52a789e1e77..1437ff36e91c 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
@@ -574,6 +574,11 @@ static int nvme_revalidate_disk(struct gendisk *disk) | |||
574 | ns->type = NVME_NS_LIGHTNVM; | 574 | ns->type = NVME_NS_LIGHTNVM; |
575 | } | 575 | } |
576 | 576 | ||
577 | if (ns->ctrl->vs >= NVME_VS(1, 1)) | ||
578 | memcpy(ns->eui, id->eui64, sizeof(ns->eui)); | ||
579 | if (ns->ctrl->vs >= NVME_VS(1, 2)) | ||
580 | memcpy(ns->uuid, id->nguid, sizeof(ns->uuid)); | ||
581 | |||
577 | old_ms = ns->ms; | 582 | old_ms = ns->ms; |
578 | lbaf = id->flbas & NVME_NS_FLBAS_LBA_MASK; | 583 | lbaf = id->flbas & NVME_NS_FLBAS_LBA_MASK; |
579 | ns->lba_shift = id->lbaf[lbaf].ds; | 584 | ns->lba_shift = id->lbaf[lbaf].ds; |
@@ -964,6 +969,59 @@ static ssize_t nvme_sysfs_reset(struct device *dev, | |||
964 | } | 969 | } |
965 | static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset); | 970 | static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset); |
966 | 971 | ||
972 | static ssize_t uuid_show(struct device *dev, struct device_attribute *attr, | ||
973 | char *buf) | ||
974 | { | ||
975 | struct nvme_ns *ns = dev_to_disk(dev)->private_data; | ||
976 | return sprintf(buf, "%pU\n", ns->uuid); | ||
977 | } | ||
978 | static DEVICE_ATTR(uuid, S_IRUGO, uuid_show, NULL); | ||
979 | |||
980 | static ssize_t eui_show(struct device *dev, struct device_attribute *attr, | ||
981 | char *buf) | ||
982 | { | ||
983 | struct nvme_ns *ns = dev_to_disk(dev)->private_data; | ||
984 | return sprintf(buf, "%8phd\n", ns->eui); | ||
985 | } | ||
986 | static DEVICE_ATTR(eui, S_IRUGO, eui_show, NULL); | ||
987 | |||
988 | static ssize_t nsid_show(struct device *dev, struct device_attribute *attr, | ||
989 | char *buf) | ||
990 | { | ||
991 | struct nvme_ns *ns = dev_to_disk(dev)->private_data; | ||
992 | return sprintf(buf, "%d\n", ns->ns_id); | ||
993 | } | ||
994 | static DEVICE_ATTR(nsid, S_IRUGO, nsid_show, NULL); | ||
995 | |||
996 | static struct attribute *nvme_ns_attrs[] = { | ||
997 | &dev_attr_uuid.attr, | ||
998 | &dev_attr_eui.attr, | ||
999 | &dev_attr_nsid.attr, | ||
1000 | NULL, | ||
1001 | }; | ||
1002 | |||
1003 | static umode_t nvme_attrs_are_visible(struct kobject *kobj, | ||
1004 | struct attribute *a, int n) | ||
1005 | { | ||
1006 | struct device *dev = container_of(kobj, struct device, kobj); | ||
1007 | struct nvme_ns *ns = dev_to_disk(dev)->private_data; | ||
1008 | |||
1009 | if (a == &dev_attr_uuid.attr) { | ||
1010 | if (!memchr_inv(ns->uuid, 0, sizeof(ns->uuid))) | ||
1011 | return 0; | ||
1012 | } | ||
1013 | if (a == &dev_attr_eui.attr) { | ||
1014 | if (!memchr_inv(ns->eui, 0, sizeof(ns->eui))) | ||
1015 | return 0; | ||
1016 | } | ||
1017 | return a->mode; | ||
1018 | } | ||
1019 | |||
1020 | static const struct attribute_group nvme_ns_attr_group = { | ||
1021 | .attrs = nvme_ns_attrs, | ||
1022 | .is_visible = nvme_attrs_are_visible, | ||
1023 | }; | ||
1024 | |||
967 | static int ns_cmp(void *priv, struct list_head *a, struct list_head *b) | 1025 | static int ns_cmp(void *priv, struct list_head *a, struct list_head *b) |
968 | { | 1026 | { |
969 | struct nvme_ns *nsa = container_of(a, struct nvme_ns, list); | 1027 | struct nvme_ns *nsa = container_of(a, struct nvme_ns, list); |
@@ -1038,9 +1096,14 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) | |||
1038 | 1096 | ||
1039 | list_add_tail(&ns->list, &ctrl->namespaces); | 1097 | list_add_tail(&ns->list, &ctrl->namespaces); |
1040 | kref_get(&ctrl->kref); | 1098 | kref_get(&ctrl->kref); |
1041 | if (ns->type != NVME_NS_LIGHTNVM) | 1099 | if (ns->type == NVME_NS_LIGHTNVM) |
1042 | add_disk(ns->disk); | 1100 | return; |
1043 | 1101 | ||
1102 | add_disk(ns->disk); | ||
1103 | if (sysfs_create_group(&disk_to_dev(ns->disk)->kobj, | ||
1104 | &nvme_ns_attr_group)) | ||
1105 | pr_warn("%s: failed to create sysfs group for identification\n", | ||
1106 | ns->disk->disk_name); | ||
1044 | return; | 1107 | return; |
1045 | out_free_disk: | 1108 | out_free_disk: |
1046 | kfree(disk); | 1109 | kfree(disk); |
@@ -1060,6 +1123,8 @@ static void nvme_ns_remove(struct nvme_ns *ns) | |||
1060 | if (ns->disk->flags & GENHD_FL_UP) { | 1123 | if (ns->disk->flags & GENHD_FL_UP) { |
1061 | if (blk_get_integrity(ns->disk)) | 1124 | if (blk_get_integrity(ns->disk)) |
1062 | blk_integrity_unregister(ns->disk); | 1125 | blk_integrity_unregister(ns->disk); |
1126 | sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, | ||
1127 | &nvme_ns_attr_group); | ||
1063 | del_gendisk(ns->disk); | 1128 | del_gendisk(ns->disk); |
1064 | } | 1129 | } |
1065 | if (kill || !blk_queue_dying(ns->queue)) { | 1130 | if (kill || !blk_queue_dying(ns->queue)) { |
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index b0417622d27c..d88cf45fbcc1 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h | |||
@@ -102,6 +102,9 @@ struct nvme_ns { | |||
102 | struct gendisk *disk; | 102 | struct gendisk *disk; |
103 | struct kref kref; | 103 | struct kref kref; |
104 | 104 | ||
105 | u8 eui[8]; | ||
106 | u8 uuid[16]; | ||
107 | |||
105 | unsigned ns_id; | 108 | unsigned ns_id; |
106 | int lba_shift; | 109 | int lba_shift; |
107 | u16 ms; | 110 | u16 ms; |