aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/bus.c23
-rw-r--r--drivers/base/core.c22
-rw-r--r--drivers/base/driver.c22
-rw-r--r--fs/sysfs/group.c54
-rw-r--r--include/linux/sysfs.h4
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)
884static int bus_add_groups(struct bus_type *bus, 884static int bus_add_groups(struct bus_type *bus,
885 const struct attribute_group **groups) 885 const struct attribute_group **groups)
886{ 886{
887 int error = 0; 887 return sysfs_create_groups(&bus->p->subsys.kobj, groups);
888 int i;
889
890 if (groups) {
891 for (i = 0; groups[i]; i++) {
892 error = sysfs_create_group(&bus->p->subsys.kobj,
893 groups[i]);
894 if (error) {
895 while (--i >= 0)
896 sysfs_remove_group(&bus->p->subsys.kobj,
897 groups[i]);
898 break;
899 }
900 }
901 }
902 return error;
903} 888}
904 889
905static void bus_remove_groups(struct bus_type *bus, 890static void bus_remove_groups(struct bus_type *bus,
906 const struct attribute_group **groups) 891 const struct attribute_group **groups)
907{ 892{
908 int i; 893 sysfs_remove_groups(&bus->p->subsys.kobj, groups);
909
910 if (groups)
911 for (i = 0; groups[i]; i++)
912 sysfs_remove_group(&bus->p->subsys.kobj, groups[i]);
913} 894}
914 895
915static void klist_devices_get(struct klist_node *n) 896static 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,
493 493
494int device_add_groups(struct device *dev, const struct attribute_group **groups) 494int device_add_groups(struct device *dev, const struct attribute_group **groups)
495{ 495{
496 int error = 0; 496 return sysfs_create_groups(&dev->kobj, groups);
497 int i;
498
499 if (groups) {
500 for (i = 0; groups[i]; i++) {
501 error = sysfs_create_group(&dev->kobj, groups[i]);
502 if (error) {
503 while (--i >= 0)
504 sysfs_remove_group(&dev->kobj,
505 groups[i]);
506 break;
507 }
508 }
509 }
510 return error;
511} 497}
512 498
513void device_remove_groups(struct device *dev, 499void device_remove_groups(struct device *dev,
514 const struct attribute_group **groups) 500 const struct attribute_group **groups)
515{ 501{
516 int i; 502 sysfs_remove_groups(&dev->kobj, groups);
517
518 if (groups)
519 for (i = 0; groups[i]; i++)
520 sysfs_remove_group(&dev->kobj, groups[i]);
521} 503}
522 504
523static int device_add_attrs(struct device *dev) 505static 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);
126int driver_add_groups(struct device_driver *drv, 126int driver_add_groups(struct device_driver *drv,
127 const struct attribute_group **groups) 127 const struct attribute_group **groups)
128{ 128{
129 int error = 0; 129 return sysfs_create_groups(&drv->p->kobj, groups);
130 int i;
131
132 if (groups) {
133 for (i = 0; groups[i]; i++) {
134 error = sysfs_create_group(&drv->p->kobj, groups[i]);
135 if (error) {
136 while (--i >= 0)
137 sysfs_remove_group(&drv->p->kobj,
138 groups[i]);
139 break;
140 }
141 }
142 }
143 return error;
144} 130}
145 131
146void driver_remove_groups(struct device_driver *drv, 132void driver_remove_groups(struct device_driver *drv,
147 const struct attribute_group **groups) 133 const struct attribute_group **groups)
148{ 134{
149 int i; 135 sysfs_remove_groups(&drv->p->kobj, groups);
150
151 if (groups)
152 for (i = 0; groups[i]; i++)
153 sysfs_remove_group(&drv->p->kobj, groups[i]);
154} 136}
155 137
156/** 138/**
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,
131} 131}
132 132
133/** 133/**
134 * sysfs_create_groups - given a directory kobject, create a bunch of attribute groups
135 * @kobj: The kobject to create the group on
136 * @groups: The attribute groups to create, NULL terminated
137 *
138 * This function creates a bunch of attribute groups. If an error occurs when
139 * creating a group, all previously created groups will be removed, unwinding
140 * everything back to the original state when this function was called.
141 * It will explicitly warn and error if any of the attribute files being
142 * created already exist.
143 *
144 * Returns 0 on success or error code from sysfs_create_groups on error.
145 */
146int sysfs_create_groups(struct kobject *kobj,
147 const struct attribute_group **groups)
148{
149 int error = 0;
150 int i;
151
152 if (!groups)
153 return 0;
154
155 for (i = 0; groups[i]; i++) {
156 error = sysfs_create_group(kobj, groups[i]);
157 if (error) {
158 while (--i >= 0)
159 sysfs_remove_group(kobj, groups[i]);
160 break;
161 }
162 }
163 return error;
164}
165EXPORT_SYMBOL_GPL(sysfs_create_groups);
166
167/**
134 * sysfs_update_group - given a directory kobject, update an attribute group 168 * sysfs_update_group - given a directory kobject, update an attribute group
135 * @kobj: The kobject to update the group on 169 * @kobj: The kobject to update the group on
136 * @grp: The attribute group to update 170 * @grp: The attribute group to update
@@ -179,6 +213,26 @@ void sysfs_remove_group(struct kobject * kobj,
179} 213}
180 214
181/** 215/**
216 * sysfs_remove_groups - remove a list of groups
217 *
218 * kobj: The kobject for the groups to be removed from
219 * groups: NULL terminated list of groups to be removed
220 *
221 * If groups is not NULL, the all groups will be removed from the kobject
222 */
223void sysfs_remove_groups(struct kobject *kobj,
224 const struct attribute_group **groups)
225{
226 int i;
227
228 if (!groups)
229 return;
230 for (i = 0; groups[i]; i++)
231 sysfs_remove_group(kobj, groups[i]);
232}
233EXPORT_SYMBOL_GPL(sysfs_remove_groups);
234
235/**
182 * sysfs_merge_group - merge files into a pre-existing attribute group. 236 * sysfs_merge_group - merge files into a pre-existing attribute group.
183 * @kobj: The kobject containing the group. 237 * @kobj: The kobject containing the group.
184 * @grp: The files to create and the attribute group they belong to. 238 * @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,
215 215
216int __must_check sysfs_create_group(struct kobject *kobj, 216int __must_check sysfs_create_group(struct kobject *kobj,
217 const struct attribute_group *grp); 217 const struct attribute_group *grp);
218int __must_check sysfs_create_groups(struct kobject *kobj,
219 const struct attribute_group **groups);
218int sysfs_update_group(struct kobject *kobj, 220int sysfs_update_group(struct kobject *kobj,
219 const struct attribute_group *grp); 221 const struct attribute_group *grp);
220void sysfs_remove_group(struct kobject *kobj, 222void sysfs_remove_group(struct kobject *kobj,
221 const struct attribute_group *grp); 223 const struct attribute_group *grp);
224void sysfs_remove_groups(struct kobject *kobj,
225 const struct attribute_group **groups);
222int sysfs_add_file_to_group(struct kobject *kobj, 226int sysfs_add_file_to_group(struct kobject *kobj,
223 const struct attribute *attr, const char *group); 227 const struct attribute *attr, const char *group);
224void sysfs_remove_file_from_group(struct kobject *kobj, 228void sysfs_remove_file_from_group(struct kobject *kobj,