|
@@ -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);
|
|
|
}
|