diff options
-rw-r--r-- | drivers/base/bus.c | 23 | ||||
-rw-r--r-- | drivers/base/core.c | 22 | ||||
-rw-r--r-- | drivers/base/driver.c | 22 | ||||
-rw-r--r-- | fs/sysfs/group.c | 54 | ||||
-rw-r--r-- | include/linux/sysfs.h | 4 |
5 files changed, 64 insertions, 61 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 5ee5d3c1d74b..f099af0b41af 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -884,32 +884,13 @@ static void bus_remove_attrs(struct bus_type *bus) static int bus_add_groups(struct bus_type *bus, const struct attribute_group **groups) { - int error = 0; - int i; - - if (groups) { - for (i = 0; groups[i]; i++) { - error = sysfs_create_group(&bus->p->subsys.kobj, - groups[i]); - if (error) { - while (--i >= 0) - sysfs_remove_group(&bus->p->subsys.kobj, - groups[i]); - break; - } - } - } - return error; + return sysfs_create_groups(&bus->p->subsys.kobj, groups); } static void bus_remove_groups(struct bus_type *bus, const struct attribute_group **groups) { - int i; - - if (groups) - for (i = 0; groups[i]; i++) - sysfs_remove_group(&bus->p->subsys.kobj, groups[i]); + sysfs_remove_groups(&bus->p->subsys.kobj, groups); } static void klist_devices_get(struct klist_node *n) diff --git a/drivers/base/core.c b/drivers/base/core.c index af646afa5b7e..d743dcee1e77 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -493,31 +493,13 @@ static void device_remove_bin_attributes(struct device *dev, int device_add_groups(struct device *dev, const struct attribute_group **groups) { - int error = 0; - int i; - - if (groups) { - for (i = 0; groups[i]; i++) { - error = sysfs_create_group(&dev->kobj, groups[i]); - if (error) { - while (--i >= 0) - sysfs_remove_group(&dev->kobj, - groups[i]); - break; - } - } - } - return error; + return sysfs_create_groups(&dev->kobj, groups); } void device_remove_groups(struct device *dev, const struct attribute_group **groups) { - int i; - - if (groups) - for (i = 0; groups[i]; i++) - sysfs_remove_group(&dev->kobj, groups[i]); + sysfs_remove_groups(&dev->kobj, groups); } static int device_add_attrs(struct device *dev) diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 89db726ebb98..c7efccb6f3bb 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -126,31 +126,13 @@ EXPORT_SYMBOL_GPL(driver_remove_file); int driver_add_groups(struct device_driver *drv, const struct attribute_group **groups) { - int error = 0; - int i; - - if (groups) { - for (i = 0; groups[i]; i++) { - error = sysfs_create_group(&drv->p->kobj, groups[i]); - if (error) { - while (--i >= 0) - sysfs_remove_group(&drv->p->kobj, - groups[i]); - break; - } - } - } - return error; + return sysfs_create_groups(&drv->p->kobj, groups); } void driver_remove_groups(struct device_driver *drv, const struct attribute_group **groups) { - int i; - - if (groups) - for (i = 0; groups[i]; i++) - sysfs_remove_group(&drv->p->kobj, groups[i]); + sysfs_remove_groups(&drv->p->kobj, groups); } /** diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 09a1a25cd145..68baf8501552 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -131,6 +131,40 @@ int sysfs_create_group(struct kobject *kobj, } /** + * sysfs_create_groups - given a directory kobject, create a bunch of attribute groups + * @kobj: The kobject to create the group on + * @groups: The attribute groups to create, NULL terminated + * + * This function creates a bunch of attribute groups. If an error occurs when + * creating a group, all previously created groups will be removed, unwinding + * everything back to the original state when this function was called. + * It will explicitly warn and error if any of the attribute files being + * created already exist. + * + * Returns 0 on success or error code from sysfs_create_groups on error. + */ +int sysfs_create_groups(struct kobject *kobj, + const struct attribute_group **groups) +{ + int error = 0; + int i; + + if (!groups) + return 0; + + for (i = 0; groups[i]; i++) { + error = sysfs_create_group(kobj, groups[i]); + if (error) { + while (--i >= 0) + sysfs_remove_group(kobj, groups[i]); + break; + } + } + return error; +} +EXPORT_SYMBOL_GPL(sysfs_create_groups); + +/** * sysfs_update_group - given a directory kobject, update an attribute group * @kobj: The kobject to update the group on * @grp: The attribute group to update @@ -179,6 +213,26 @@ void sysfs_remove_group(struct kobject * kobj, } /** + * sysfs_remove_groups - remove a list of groups + * + * kobj: The kobject for the groups to be removed from + * groups: NULL terminated list of groups to be removed + * + * If groups is not NULL, the all groups will be removed from the kobject + */ +void sysfs_remove_groups(struct kobject *kobj, + const struct attribute_group **groups) +{ + int i; + + if (!groups) + return; + for (i = 0; groups[i]; i++) + sysfs_remove_group(kobj, groups[i]); +} +EXPORT_SYMBOL_GPL(sysfs_remove_groups); + +/** * sysfs_merge_group - merge files into a pre-existing attribute group. * @kobj: The kobject containing the group. * @grp: The files to create and the attribute group they belong to. diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 0f04958623d7..4dbb9d31daa8 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -215,10 +215,14 @@ void sysfs_delete_link(struct kobject *dir, struct kobject *targ, int __must_check sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp); +int __must_check sysfs_create_groups(struct kobject *kobj, + const struct attribute_group **groups); int sysfs_update_group(struct kobject *kobj, const struct attribute_group *grp); void sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp); +void sysfs_remove_groups(struct kobject *kobj, + const struct attribute_group **groups); int sysfs_add_file_to_group(struct kobject *kobj, const struct attribute *attr, const char *group); void sysfs_remove_file_from_group(struct kobject *kobj, |