aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-21 16:47:50 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-21 19:02:19 -0400
commit3e9b2bae8369661070622d05570cbcdfa01770e6 (patch)
treea5e22d5953306740dca0da253752ad6830baaa50
parentfa2be40fe7c0aa3b7accbf6dfa9ef0976e191d4c (diff)
sysfs: add sysfs_create/remove_groups()
These functions are being open-coded in 3 different places in the driver core, and other driver subsystems will want to start doing this as well, so move it to the sysfs core to keep it all in one place, where we know it is written properly. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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,