diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2012-10-01 03:12:01 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-10-09 08:16:56 -0400 |
commit | 521b3d790c16fad9d83c72d610c1e416ad3f7ae3 (patch) | |
tree | 978471e1dbd99661933903e0840c6d80a1ff9cc0 /drivers/s390 | |
parent | 85e9d0e5ffabfede5facbac5b0d9b90768bc6e90 (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.c | 52 |
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); |
70 | static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf, | 70 | static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf, |
71 | size_t count); | 71 | size_t count); |
72 | static ssize_t dcssblk_save_store(struct device * dev, struct device_attribute *attr, const char * buf, | ||
73 | size_t count); | ||
74 | static ssize_t dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf); | ||
75 | static ssize_t dcssblk_shared_store(struct device * dev, struct device_attribute *attr, const char * buf, | ||
76 | size_t count); | ||
77 | static ssize_t dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf); | ||
78 | static ssize_t dcssblk_seglist_show(struct device *dev, | ||
79 | struct device_attribute *attr, | ||
80 | char *buf); | ||
81 | 72 | ||
82 | static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store); | 73 | static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store); |
83 | static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store); | 74 | static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store); |
84 | static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show, | ||
85 | dcssblk_save_store); | ||
86 | static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show, | ||
87 | dcssblk_shared_store); | ||
88 | static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL); | ||
89 | 75 | ||
90 | static struct device *dcssblk_root_dev; | 76 | static 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 | } |
405 | static 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 | } |
467 | static 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 | } |
495 | static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL); | ||
496 | |||
497 | static struct attribute *dcssblk_dev_attrs[] = { | ||
498 | &dev_attr_shared.attr, | ||
499 | &dev_attr_save.attr, | ||
500 | &dev_attr_seglist.attr, | ||
501 | NULL, | ||
502 | }; | ||
503 | static struct attribute_group dcssblk_dev_attr_group = { | ||
504 | .attrs = dcssblk_dev_attrs, | ||
505 | }; | ||
506 | static 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 | ||
671 | unregister_dev: | 666 | put_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 | } |