aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2012-10-01 03:12:01 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-10-09 08:16:56 -0400
commit521b3d790c16fad9d83c72d610c1e416ad3f7ae3 (patch)
tree978471e1dbd99661933903e0840c6d80a1ff9cc0 /drivers/s390
parent85e9d0e5ffabfede5facbac5b0d9b90768bc6e90 (diff)
s390/dcssblk: cleanup device attribute usage
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>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dcssblk.c52
1 files changed, 23 insertions, 29 deletions
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index a5a55da2a1a..b6ad0de0793 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -69,23 +69,9 @@ static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *a
69 size_t count); 69 size_t count);
70static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf, 70static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf,
71 size_t count); 71 size_t count);
72static ssize_t dcssblk_save_store(struct device * dev, struct device_attribute *attr, const char * buf,
73 size_t count);
74static ssize_t dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf);
75static ssize_t dcssblk_shared_store(struct device * dev, struct device_attribute *attr, const char * buf,
76 size_t count);
77static ssize_t dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf);
78static ssize_t dcssblk_seglist_show(struct device *dev,
79 struct device_attribute *attr,
80 char *buf);
81 72
82static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store); 73static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store);
83static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store); 74static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store);
84static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show,
85 dcssblk_save_store);
86static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show,
87 dcssblk_shared_store);
88static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL);
89 75
90static struct device *dcssblk_root_dev; 76static struct device *dcssblk_root_dev;
91 77
@@ -416,6 +402,8 @@ out:
416 up_write(&dcssblk_devices_sem); 402 up_write(&dcssblk_devices_sem);
417 return rc; 403 return rc;
418} 404}
405static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show,
406 dcssblk_shared_store);
419 407
420/* 408/*
421 * device attribute for save operation on current copy 409 * device attribute for save operation on current copy
@@ -476,6 +464,8 @@ dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char
476 up_write(&dcssblk_devices_sem); 464 up_write(&dcssblk_devices_sem);
477 return count; 465 return count;
478} 466}
467static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show,
468 dcssblk_save_store);
479 469
480/* 470/*
481 * device attribute for showing all segments in a device 471 * device attribute for showing all segments in a device
@@ -502,6 +492,21 @@ dcssblk_seglist_show(struct device *dev, struct device_attribute *attr,
502 up_read(&dcssblk_devices_sem); 492 up_read(&dcssblk_devices_sem);
503 return i; 493 return i;
504} 494}
495static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL);
496
497static struct attribute *dcssblk_dev_attrs[] = {
498 &dev_attr_shared.attr,
499 &dev_attr_save.attr,
500 &dev_attr_seglist.attr,
501 NULL,
502};
503static struct attribute_group dcssblk_dev_attr_group = {
504 .attrs = dcssblk_dev_attrs,
505};
506static const struct attribute_group *dcssblk_dev_attr_groups[] = {
507 &dcssblk_dev_attr_group,
508 NULL,
509};
505 510
506/* 511/*
507 * device attribute for adding devices 512 * device attribute for adding devices
@@ -590,6 +595,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
590 595
591 dev_set_name(&dev_info->dev, dev_info->segment_name); 596 dev_set_name(&dev_info->dev, dev_info->segment_name);
592 dev_info->dev.release = dcssblk_release_segment; 597 dev_info->dev.release = dcssblk_release_segment;
598 dev_info->dev.groups = dcssblk_dev_attr_groups;
593 INIT_LIST_HEAD(&dev_info->lh); 599 INIT_LIST_HEAD(&dev_info->lh);
594 dev_info->gd = alloc_disk(DCSSBLK_MINORS_PER_DISK); 600 dev_info->gd = alloc_disk(DCSSBLK_MINORS_PER_DISK);
595 if (dev_info->gd == NULL) { 601 if (dev_info->gd == NULL) {
@@ -637,21 +643,10 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
637 * register the device 643 * register the device
638 */ 644 */
639 rc = device_register(&dev_info->dev); 645 rc = device_register(&dev_info->dev);
640 if (rc) {
641 module_put(THIS_MODULE);
642 goto dev_list_del;
643 }
644 get_device(&dev_info->dev);
645 rc = device_create_file(&dev_info->dev, &dev_attr_shared);
646 if (rc)
647 goto unregister_dev;
648 rc = device_create_file(&dev_info->dev, &dev_attr_save);
649 if (rc)
650 goto unregister_dev;
651 rc = device_create_file(&dev_info->dev, &dev_attr_seglist);
652 if (rc) 646 if (rc)
653 goto unregister_dev; 647 goto put_dev;
654 648
649 get_device(&dev_info->dev);
655 add_disk(dev_info->gd); 650 add_disk(dev_info->gd);
656 651
657 switch (dev_info->segment_type) { 652 switch (dev_info->segment_type) {
@@ -668,12 +663,11 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
668 rc = count; 663 rc = count;
669 goto out; 664 goto out;
670 665
671unregister_dev: 666put_dev:
672 list_del(&dev_info->lh); 667 list_del(&dev_info->lh);
673 blk_cleanup_queue(dev_info->dcssblk_queue); 668 blk_cleanup_queue(dev_info->dcssblk_queue);
674 dev_info->gd->queue = NULL; 669 dev_info->gd->queue = NULL;
675 put_disk(dev_info->gd); 670 put_disk(dev_info->gd);
676 device_unregister(&dev_info->dev);
677 list_for_each_entry(seg_info, &dev_info->seg_list, lh) { 671 list_for_each_entry(seg_info, &dev_info->seg_list, lh) {
678 segment_unload(seg_info->segment_name); 672 segment_unload(seg_info->segment_name);
679 } 673 }