s390/dcssblk: cleanup device attribute usage
authorSebastian Ott <sebott@linux.vnet.ibm.com>
Mon, 1 Oct 2012 07:12:01 +0000 (09:12 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 9 Oct 2012 12:16:56 +0000 (14:16 +0200)
Let the driver core handle device attribute creation and removal. This
will simplify the code and eliminates races between attribute
availability and userspace notification via uevents.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/block/dcssblk.c

index a5a55da2a1ac14752c426f4a0a00e4fb4f11521c..b6ad0de07930c531f9a81f8314a1b6b974e9d6db 100644 (file)
@@ -69,23 +69,9 @@ static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *a
                                  size_t count);
 static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf,
                                  size_t count);
-static ssize_t dcssblk_save_store(struct device * dev, struct device_attribute *attr, const char * buf,
-                                 size_t count);
-static ssize_t dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t dcssblk_shared_store(struct device * dev, struct device_attribute *attr, const char * buf,
-                                 size_t count);
-static ssize_t dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t dcssblk_seglist_show(struct device *dev,
-                               struct device_attribute *attr,
-                               char *buf);
 
 static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store);
 static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store);
-static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show,
-                  dcssblk_save_store);
-static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show,
-                  dcssblk_shared_store);
-static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL);
 
 static struct device *dcssblk_root_dev;
 
@@ -416,6 +402,8 @@ out:
        up_write(&dcssblk_devices_sem);
        return rc;
 }
+static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show,
+                  dcssblk_shared_store);
 
 /*
  * device attribute for save operation on current copy
@@ -476,6 +464,8 @@ dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char
        up_write(&dcssblk_devices_sem);
        return count;
 }
+static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show,
+                  dcssblk_save_store);
 
 /*
  * device attribute for showing all segments in a device
@@ -502,6 +492,21 @@ dcssblk_seglist_show(struct device *dev, struct device_attribute *attr,
        up_read(&dcssblk_devices_sem);
        return i;
 }
+static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL);
+
+static struct attribute *dcssblk_dev_attrs[] = {
+       &dev_attr_shared.attr,
+       &dev_attr_save.attr,
+       &dev_attr_seglist.attr,
+       NULL,
+};
+static struct attribute_group dcssblk_dev_attr_group = {
+       .attrs = dcssblk_dev_attrs,
+};
+static const struct attribute_group *dcssblk_dev_attr_groups[] = {
+       &dcssblk_dev_attr_group,
+       NULL,
+};
 
 /*
  * device attribute for adding devices
@@ -590,6 +595,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
 
        dev_set_name(&dev_info->dev, dev_info->segment_name);
        dev_info->dev.release = dcssblk_release_segment;
+       dev_info->dev.groups = dcssblk_dev_attr_groups;
        INIT_LIST_HEAD(&dev_info->lh);
        dev_info->gd = alloc_disk(DCSSBLK_MINORS_PER_DISK);
        if (dev_info->gd == NULL) {
@@ -637,21 +643,10 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
         * register the device
         */
        rc = device_register(&dev_info->dev);
-       if (rc) {
-               module_put(THIS_MODULE);
-               goto dev_list_del;
-       }
-       get_device(&dev_info->dev);
-       rc = device_create_file(&dev_info->dev, &dev_attr_shared);
-       if (rc)
-               goto unregister_dev;
-       rc = device_create_file(&dev_info->dev, &dev_attr_save);
-       if (rc)
-               goto unregister_dev;
-       rc = device_create_file(&dev_info->dev, &dev_attr_seglist);
        if (rc)
-               goto unregister_dev;
+               goto put_dev;
 
+       get_device(&dev_info->dev);
        add_disk(dev_info->gd);
 
        switch (dev_info->segment_type) {
@@ -668,12 +663,11 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
        rc = count;
        goto out;
 
-unregister_dev:
+put_dev:
        list_del(&dev_info->lh);
        blk_cleanup_queue(dev_info->dcssblk_queue);
        dev_info->gd->queue = NULL;
        put_disk(dev_info->gd);
-       device_unregister(&dev_info->dev);
        list_for_each_entry(seg_info, &dev_info->seg_list, lh) {
                segment_unload(seg_info->segment_name);
        }