Commit 33b14f67 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Jens Axboe

nvme: register ns_id attributes as default sysfs groups

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: default avatarBart van Assche <bvanassche@acm.org>
Reviewed-by: default avatarKeith Busch <keith.busch@intel.com>
Signed-off-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent fef912bf
...@@ -2734,6 +2734,14 @@ const struct attribute_group nvme_ns_id_attr_group = { ...@@ -2734,6 +2734,14 @@ const struct attribute_group nvme_ns_id_attr_group = {
.is_visible = nvme_ns_id_attrs_are_visible, .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) \ #define nvme_show_str_function(field) \
static ssize_t field##_show(struct device *dev, \ static ssize_t field##_show(struct device *dev, \
struct device_attribute *attr, char *buf) \ struct device_attribute *attr, char *buf) \
...@@ -3099,14 +3107,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) ...@@ -3099,14 +3107,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
nvme_get_ctrl(ctrl); nvme_get_ctrl(ctrl);
device_add_disk(ctrl->device, ns->disk, NULL); device_add_disk(ctrl->device, ns->disk, nvme_ns_id_attr_groups);
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);
nvme_mpath_add_disk(ns, id); nvme_mpath_add_disk(ns, id);
nvme_fault_inject_init(ns); nvme_fault_inject_init(ns);
...@@ -3132,10 +3133,6 @@ static void nvme_ns_remove(struct nvme_ns *ns) ...@@ -3132,10 +3133,6 @@ static void nvme_ns_remove(struct nvme_ns *ns)
nvme_fault_inject_fini(ns); nvme_fault_inject_fini(ns);
if (ns->disk && ns->disk->flags & GENHD_FL_UP) { 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); del_gendisk(ns->disk);
blk_cleanup_queue(ns->queue); blk_cleanup_queue(ns->queue);
if (blk_get_integrity(ns->disk)) if (blk_get_integrity(ns->disk))
......
...@@ -1190,10 +1190,29 @@ static NVM_DEV_ATTR_12_RO(multiplane_modes); ...@@ -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(media_capabilities);
static NVM_DEV_ATTR_12_RO(max_phys_secs); 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_version.attr,
&dev_attr_capabilities.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_vendor_opcode.attr,
&dev_attr_device_mode.attr, &dev_attr_device_mode.attr,
&dev_attr_media_manager.attr, &dev_attr_media_manager.attr,
...@@ -1208,8 +1227,6 @@ static struct attribute *nvm_dev_attrs_12[] = { ...@@ -1208,8 +1227,6 @@ static struct attribute *nvm_dev_attrs_12[] = {
&dev_attr_page_size.attr, &dev_attr_page_size.attr,
&dev_attr_hw_sector_size.attr, &dev_attr_hw_sector_size.attr,
&dev_attr_oob_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_typ.attr,
&dev_attr_prog_max.attr, &dev_attr_prog_max.attr,
&dev_attr_erase_typ.attr, &dev_attr_erase_typ.attr,
...@@ -1218,33 +1235,7 @@ static struct attribute *nvm_dev_attrs_12[] = { ...@@ -1218,33 +1235,7 @@ static struct attribute *nvm_dev_attrs_12[] = {
&dev_attr_media_capabilities.attr, &dev_attr_media_capabilities.attr,
&dev_attr_max_phys_secs.attr, &dev_attr_max_phys_secs.attr,
NULL, /* 2.0 attrs */
};
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,
&dev_attr_groups.attr, &dev_attr_groups.attr,
&dev_attr_punits.attr, &dev_attr_punits.attr,
&dev_attr_chunks.attr, &dev_attr_chunks.attr,
...@@ -1255,8 +1246,6 @@ static struct attribute *nvm_dev_attrs_20[] = { ...@@ -1255,8 +1246,6 @@ static struct attribute *nvm_dev_attrs_20[] = {
&dev_attr_maxocpu.attr, &dev_attr_maxocpu.attr,
&dev_attr_mw_cunits.attr, &dev_attr_mw_cunits.attr,
&dev_attr_read_typ.attr,
&dev_attr_read_max.attr,
&dev_attr_write_typ.attr, &dev_attr_write_typ.attr,
&dev_attr_write_max.attr, &dev_attr_write_max.attr,
&dev_attr_reset_typ.attr, &dev_attr_reset_typ.attr,
...@@ -1265,44 +1254,38 @@ static struct attribute *nvm_dev_attrs_20[] = { ...@@ -1265,44 +1254,38 @@ static struct attribute *nvm_dev_attrs_20[] = {
NULL, NULL,
}; };
static const struct attribute_group nvm_dev_attr_group_20 = { static umode_t nvm_dev_attrs_visible(struct kobject *kobj,
.name = "lightnvm", struct attribute *attr, int index)
.attrs = nvm_dev_attrs_20,
};
int nvme_nvm_register_sysfs(struct nvme_ns *ns)
{ {
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_dev *ndev = ns->ndev;
struct nvm_geo *geo = &ndev->geo; struct device_attribute *dev_attr =
container_of(attr, typeof(*dev_attr), attr);
if (!ndev) if (!ndev)
return -EINVAL; return 0;
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;
}
void nvme_nvm_unregister_sysfs(struct nvme_ns *ns) if (dev_attr->show == nvm_dev_attr_show)
{ return attr->mode;
struct nvm_dev *ndev = ns->ndev;
struct nvm_geo *geo = &ndev->geo;
switch (geo->major_ver_id) { switch (ndev->geo.major_ver_id) {
case 1: case 1:
sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, if (dev_attr->show == nvm_dev_attr_show_12)
&nvm_dev_attr_group_12); return attr->mode;
break; break;
case 2: case 2:
sysfs_remove_group(&disk_to_dev(ns->disk)->kobj, if (dev_attr->show == nvm_dev_attr_show_20)
&nvm_dev_attr_group_20); return attr->mode;
break; break;
} }
return 0;
} }
const struct attribute_group nvme_nvm_attr_group = {
.name = "lightnvm",
.attrs = nvm_dev_attrs,
.is_visible = nvm_dev_attrs_visible,
};
...@@ -282,13 +282,9 @@ static void nvme_mpath_set_live(struct nvme_ns *ns) ...@@ -282,13 +282,9 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
if (!head->disk) if (!head->disk)
return; return;
if (!(head->disk->flags & GENHD_FL_UP)) { if (!(head->disk->flags & GENHD_FL_UP))
device_add_disk(&head->subsys->dev, head->disk, NULL); device_add_disk(&head->subsys->dev, head->disk,
if (sysfs_create_group(&disk_to_dev(head->disk)->kobj, nvme_ns_id_attr_groups);
&nvme_ns_id_attr_group))
dev_warn(&head->subsys->dev,
"failed to create id group.\n");
}
kblockd_schedule_work(&ns->head->requeue_work); kblockd_schedule_work(&ns->head->requeue_work);
} }
...@@ -494,11 +490,8 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head) ...@@ -494,11 +490,8 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head)
{ {
if (!head->disk) if (!head->disk)
return; return;
if (head->disk->flags & GENHD_FL_UP) { if (head->disk->flags & GENHD_FL_UP)
sysfs_remove_group(&disk_to_dev(head->disk)->kobj,
&nvme_ns_id_attr_group);
del_gendisk(head->disk); del_gendisk(head->disk);
}
blk_set_queue_dying(head->disk->queue); blk_set_queue_dying(head->disk->queue);
/* make sure all pending bios are cleaned up */ /* make sure all pending bios are cleaned up */
kblockd_schedule_work(&head->requeue_work); kblockd_schedule_work(&head->requeue_work);
......
...@@ -459,7 +459,7 @@ int nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl); ...@@ -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, int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp,
void *log, size_t size, u64 offset); 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; extern const struct block_device_operations nvme_ns_head_ops;
#ifdef CONFIG_NVME_MULTIPATH #ifdef CONFIG_NVME_MULTIPATH
...@@ -551,8 +551,7 @@ static inline void nvme_mpath_stop(struct nvme_ctrl *ctrl) ...@@ -551,8 +551,7 @@ static inline void nvme_mpath_stop(struct nvme_ctrl *ctrl)
void nvme_nvm_update_nvm_info(struct nvme_ns *ns); void nvme_nvm_update_nvm_info(struct nvme_ns *ns);
int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node); int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node);
void nvme_nvm_unregister(struct nvme_ns *ns); void nvme_nvm_unregister(struct nvme_ns *ns);
int nvme_nvm_register_sysfs(struct nvme_ns *ns); extern const struct attribute_group nvme_nvm_attr_group;
void nvme_nvm_unregister_sysfs(struct nvme_ns *ns);
int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd, unsigned long arg); int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd, unsigned long arg);
#else #else
static inline void nvme_nvm_update_nvm_info(struct nvme_ns *ns) {}; 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, ...@@ -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 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, static inline int nvme_nvm_ioctl(struct nvme_ns *ns, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment