]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
nvme: register ns_id attributes as default sysfs groups
authorHannes Reinecke <hare@suse.de>
Fri, 28 Sep 2018 06:17:20 +0000 (08:17 +0200)
committerJens Axboe <axboe@kernel.dk>
Fri, 28 Sep 2018 14:30:29 +0000 (08:30 -0600)
We should be registering the ns_id attribute as default sysfs
attribute groups, otherwise we have a race condition between
the uevent and the attributes appearing in sysfs.

Suggested-by: Bart van Assche <bvanassche@acm.org>
Reviewed-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/nvme/host/core.c
drivers/nvme/host/lightnvm.c
drivers/nvme/host/multipath.c
drivers/nvme/host/nvme.h

index 0e824e8c8fd78ab196f53efbc3a10fec079308ca..e0a9e1c5b30e5aa429b440fdcfb411c2b7ee91a2 100644 (file)
@@ -2734,6 +2734,14 @@ const struct attribute_group nvme_ns_id_attr_group = {
        .is_visible     = nvme_ns_id_attrs_are_visible,
 };
 
+const struct attribute_group *nvme_ns_id_attr_groups[] = {
+       &nvme_ns_id_attr_group,
+#ifdef CONFIG_NVM
+       &nvme_nvm_attr_group,
+#endif
+       NULL,
+};
+
 #define nvme_show_str_function(field)                                          \
 static ssize_t  field##_show(struct device *dev,                               \
                            struct device_attribute *attr, char *buf)           \
@@ -3099,14 +3107,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 
        nvme_get_ctrl(ctrl);
 
-       device_add_disk(ctrl->device, ns->disk, NULL);
-       if (sysfs_create_group(&disk_to_dev(ns->disk)->kobj,
-                                       &nvme_ns_id_attr_group))
-               pr_warn("%s: failed to create sysfs group for identification\n",
-                       ns->disk->disk_name);
-       if (ns->ndev && nvme_nvm_register_sysfs(ns))
-               pr_warn("%s: failed to register lightnvm sysfs group for identification\n",
-                       ns->disk->disk_name);
+       device_add_disk(ctrl->device, ns->disk, nvme_ns_id_attr_groups);
 
        nvme_mpath_add_disk(ns, id);
        nvme_fault_inject_init(ns);
@@ -3132,10 +3133,6 @@ static void nvme_ns_remove(struct nvme_ns *ns)
 
        nvme_fault_inject_fini(ns);
        if (ns->disk && ns->disk->flags & GENHD_FL_UP) {
-               sysfs_remove_group(&disk_to_dev(ns->disk)->kobj,
-                                       &nvme_ns_id_attr_group);
-               if (ns->ndev)
-                       nvme_nvm_unregister_sysfs(ns);
                del_gendisk(ns->disk);
                blk_cleanup_queue(ns->queue);
                if (blk_get_integrity(ns->disk))
index 6fe5923c95d4aa1f553c76890e84ffd243b6dcdf..1e4f975388384f7719bd1ca1fd3950ea32fd829a 100644 (file)
@@ -1190,10 +1190,29 @@ static NVM_DEV_ATTR_12_RO(multiplane_modes);
 static NVM_DEV_ATTR_12_RO(media_capabilities);
 static NVM_DEV_ATTR_12_RO(max_phys_secs);
 
-static struct attribute *nvm_dev_attrs_12[] = {
+/* 2.0 values */
+static NVM_DEV_ATTR_20_RO(groups);
+static NVM_DEV_ATTR_20_RO(punits);
+static NVM_DEV_ATTR_20_RO(chunks);
+static NVM_DEV_ATTR_20_RO(clba);
+static NVM_DEV_ATTR_20_RO(ws_min);
+static NVM_DEV_ATTR_20_RO(ws_opt);
+static NVM_DEV_ATTR_20_RO(maxoc);
+static NVM_DEV_ATTR_20_RO(maxocpu);
+static NVM_DEV_ATTR_20_RO(mw_cunits);
+static NVM_DEV_ATTR_20_RO(write_typ);
+static NVM_DEV_ATTR_20_RO(write_max);
+static NVM_DEV_ATTR_20_RO(reset_typ);
+static NVM_DEV_ATTR_20_RO(reset_max);
+
+static struct attribute *nvm_dev_attrs[] = {
+       /* version agnostic attrs */
        &dev_attr_version.attr,
        &dev_attr_capabilities.attr,
+       &dev_attr_read_typ.attr,
+       &dev_attr_read_max.attr,
 
+       /* 1.2 attrs */
        &dev_attr_vendor_opcode.attr,
        &dev_attr_device_mode.attr,
        &dev_attr_media_manager.attr,
@@ -1208,8 +1227,6 @@ static struct attribute *nvm_dev_attrs_12[] = {
        &dev_attr_page_size.attr,
        &dev_attr_hw_sector_size.attr,
        &dev_attr_oob_sector_size.attr,
-       &dev_attr_read_typ.attr,
-       &dev_attr_read_max.attr,
        &dev_attr_prog_typ.attr,
        &dev_attr_prog_max.attr,
        &dev_attr_erase_typ.attr,
@@ -1218,33 +1235,7 @@ static struct attribute *nvm_dev_attrs_12[] = {
        &dev_attr_media_capabilities.attr,
        &dev_attr_max_phys_secs.attr,
 
-       NULL,
-};
-
-static const struct attribute_group nvm_dev_attr_group_12 = {
-       .name           = "lightnvm",
-       .attrs          = nvm_dev_attrs_12,
-};
-
-/* 2.0 values */
-static NVM_DEV_ATTR_20_RO(groups);
-static NVM_DEV_ATTR_20_RO(punits);
-static NVM_DEV_ATTR_20_RO(chunks);
-static NVM_DEV_ATTR_20_RO(clba);
-static NVM_DEV_ATTR_20_RO(ws_min);
-static NVM_DEV_ATTR_20_RO(ws_opt);
-static NVM_DEV_ATTR_20_RO(maxoc);
-static NVM_DEV_ATTR_20_RO(maxocpu);
-static NVM_DEV_ATTR_20_RO(mw_cunits);
-static NVM_DEV_ATTR_20_RO(write_typ);
-static NVM_DEV_ATTR_20_RO(write_max);
-static NVM_DEV_ATTR_20_RO(reset_typ);
-static NVM_DEV_ATTR_20_RO(reset_max);
-
-static struct attribute *nvm_dev_attrs_20[] = {
-       &dev_attr_version.attr,
-       &dev_attr_capabilities.attr,
-
+       /* 2.0 attrs */
        &dev_attr_groups.attr,
        &dev_attr_punits.attr,
        &dev_attr_chunks.attr,
@@ -1255,8 +1246,6 @@ static struct attribute *nvm_dev_attrs_20[] = {
        &dev_attr_maxocpu.attr,
        &dev_attr_mw_cunits.attr,
 
-       &dev_attr_read_typ.attr,
-       &dev_attr_read_max.attr,
        &dev_attr_write_typ.attr,
        &dev_attr_write_max.attr,
        &dev_attr_reset_typ.attr,
@@ -1265,44 +1254,38 @@ static struct attribute *nvm_dev_attrs_20[] = {
        NULL,
 };
 
-static const struct attribute_group nvm_dev_attr_group_20 = {
-       .name           = "lightnvm",
-       .attrs          = nvm_dev_attrs_20,
-};
-
-int nvme_nvm_register_sysfs(struct nvme_ns *ns)
+static umode_t nvm_dev_attrs_visible(struct kobject *kobj,
+                                    struct attribute *attr, int index)
 {
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct gendisk *disk = dev_to_disk(dev);
+       struct nvme_ns *ns = disk->private_data;
        struct nvm_dev *ndev = ns->ndev;
-       struct nvm_geo *geo = &ndev->geo;
+       struct device_attribute *dev_attr =
+               container_of(attr, typeof(*dev_attr), attr);
 
        if (!ndev)
-               return -EINVAL;
-
-       switch (geo->major_ver_id) {
-       case 1:
-               return sysfs_create_group(&disk_to_dev(ns->disk)->kobj,
-                                       &nvm_dev_attr_group_12);
-       case 2:
-               return sysfs_create_group(&disk_to_dev(ns->disk)->kobj,
-                                       &nvm_dev_attr_group_20);
-       }
-
-       return -EINVAL;
-}
+               return 0;
 
-void nvme_nvm_unregister_sysfs(struct nvme_ns *ns)
-{
-       struct nvm_dev *ndev = ns->ndev;
-       struct nvm_geo *geo = &ndev->geo;
+       if (dev_attr->show == nvm_dev_attr_show)
+               return attr->mode;
 
-       switch (geo->major_ver_id) {
+       switch (ndev->geo.major_ver_id) {
        case 1:
-               sysfs_remove_group(&disk_to_dev(ns->disk)->kobj,
-                                       &nvm_dev_attr_group_12);
+               if (dev_attr->show == nvm_dev_attr_show_12)
+                       return attr->mode;
                break;
        case 2:
-               sysfs_remove_group(&disk_to_dev(ns->disk)->kobj,
-                                       &nvm_dev_attr_group_20);
+               if (dev_attr->show == nvm_dev_attr_show_20)
+                       return attr->mode;
                break;
        }
+
+       return 0;
 }
+
+const struct attribute_group nvme_nvm_attr_group = {
+       .name           = "lightnvm",
+       .attrs          = nvm_dev_attrs,
+       .is_visible     = nvm_dev_attrs_visible,
+};
index 477af51d01e86abe336b5ba34f82b1c612ad46c8..8e846095c42d8f276e50277b0eac6777c322ef5a 100644 (file)
@@ -282,13 +282,9 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
        if (!head->disk)
                return;
 
-       if (!(head->disk->flags & GENHD_FL_UP)) {
-               device_add_disk(&head->subsys->dev, head->disk, NULL);
-               if (sysfs_create_group(&disk_to_dev(head->disk)->kobj,
-                               &nvme_ns_id_attr_group))
-                       dev_warn(&head->subsys->dev,
-                                "failed to create id group.\n");
-       }
+       if (!(head->disk->flags & GENHD_FL_UP))
+               device_add_disk(&head->subsys->dev, head->disk,
+                               nvme_ns_id_attr_groups);
 
        kblockd_schedule_work(&ns->head->requeue_work);
 }
@@ -494,11 +490,8 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head)
 {
        if (!head->disk)
                return;
-       if (head->disk->flags & GENHD_FL_UP) {
-               sysfs_remove_group(&disk_to_dev(head->disk)->kobj,
-                                  &nvme_ns_id_attr_group);
+       if (head->disk->flags & GENHD_FL_UP)
                del_gendisk(head->disk);
-       }
        blk_set_queue_dying(head->disk->queue);
        /* make sure all pending bios are cleaned up */
        kblockd_schedule_work(&head->requeue_work);
index bb4a2003c0978722230a1e875ade13dc8c28311f..2503f8fd54da2f158776237e754006cfa9e4767e 100644 (file)
@@ -459,7 +459,7 @@ int nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl);
 int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp,
                void *log, size_t size, u64 offset);
 
-extern const struct attribute_group nvme_ns_id_attr_group;
+extern const struct attribute_group *nvme_ns_id_attr_groups[];
 extern const struct block_device_operations nvme_ns_head_ops;
 
 #ifdef CONFIG_NVME_MULTIPATH
@@ -551,8 +551,7 @@ static inline void nvme_mpath_stop(struct nvme_ctrl *ctrl)
 void nvme_nvm_update_nvm_info(struct nvme_ns *ns);
 int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node);
 void nvme_nvm_unregister(struct nvme_ns *ns);
-int nvme_nvm_register_sysfs(struct nvme_ns *ns);
-void nvme_nvm_unregister_sysfs(struct nvme_ns *ns);
+extern const struct attribute_group nvme_nvm_attr_group;
 int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd, unsigned long arg);
 #else
 static inline void nvme_nvm_update_nvm_info(struct nvme_ns *ns) {};
@@ -563,11 +562,6 @@ static inline int nvme_nvm_register(struct nvme_ns *ns, char *disk_name,
 }
 
 static inline void nvme_nvm_unregister(struct nvme_ns *ns) {};
-static inline int nvme_nvm_register_sysfs(struct nvme_ns *ns)
-{
-       return 0;
-}
-static inline void nvme_nvm_unregister_sysfs(struct nvme_ns *ns) {};
 static inline int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd,
                                                        unsigned long arg)
 {