aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Busch <keith.busch@intel.com>2015-12-22 12:10:45 -0500
committerJens Axboe <axboe@fb.com>2015-12-22 12:10:45 -0500
commit2b9b6e86bca7209de02754fc84acf7ab3e78734e (patch)
tree1cd3492be06e261d610ef2d6eec5435ff03574a8
parenta0a3408ee614848c27b0d36c2fe490da3b387b8d (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.c69
-rw-r--r--drivers/nvme/host/nvme.h3
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}
965static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset); 970static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset);
966 971
972static 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}
978static DEVICE_ATTR(uuid, S_IRUGO, uuid_show, NULL);
979
980static 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}
986static DEVICE_ATTR(eui, S_IRUGO, eui_show, NULL);
987
988static 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}
994static DEVICE_ATTR(nsid, S_IRUGO, nsid_show, NULL);
995
996static struct attribute *nvme_ns_attrs[] = {
997 &dev_attr_uuid.attr,
998 &dev_attr_eui.attr,
999 &dev_attr_nsid.attr,
1000 NULL,
1001};
1002
1003static 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
1020static const struct attribute_group nvme_ns_attr_group = {
1021 .attrs = nvme_ns_attrs,
1022 .is_visible = nvme_attrs_are_visible,
1023};
1024
967static int ns_cmp(void *priv, struct list_head *a, struct list_head *b) 1025static 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;