aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-07-14 19:05:55 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-07-16 13:57:36 -0400
commit6ab9cea16075ea707022753395f340b67f64304c (patch)
treeb61347a5ae4f7f85ede80f5e3b5cf74e5b167ebc /fs
parentced321bf9151535f85779b0004c93529f860b2a4 (diff)
sysfs: add support for binary attributes in groups
groups should be able to support binary attributes, just like it supports "normal" attributes. This lets us only handle one type of structure, groups, throughout the driver core and subsystems, making binary attributes a "full fledged" part of the driver model, and not something just "tacked on". Reported-by: Oliver Schinagl <oliver@schinagl.nl> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Tested-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/sysfs/group.c66
1 files changed, 46 insertions, 20 deletions
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index aec3d5c98c94..e5719c6095c3 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -20,38 +20,64 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
20 const struct attribute_group *grp) 20 const struct attribute_group *grp)
21{ 21{
22 struct attribute *const* attr; 22 struct attribute *const* attr;
23 int i; 23 struct bin_attribute *const* bin_attr;
24 24
25 for (i = 0, attr = grp->attrs; *attr; i++, attr++) 25 if (grp->attrs)
26 sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name); 26 for (attr = grp->attrs; *attr; attr++)
27 sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name);
28 if (grp->bin_attrs)
29 for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++)
30 sysfs_remove_bin_file(kobj, *bin_attr);
27} 31}
28 32
29static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, 33static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
30 const struct attribute_group *grp, int update) 34 const struct attribute_group *grp, int update)
31{ 35{
32 struct attribute *const* attr; 36 struct attribute *const* attr;
37 struct bin_attribute *const* bin_attr;
33 int error = 0, i; 38 int error = 0, i;
34 39
35 for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) { 40 if (grp->attrs) {
36 umode_t mode = 0; 41 for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) {
42 umode_t mode = 0;
43
44 /*
45 * In update mode, we're changing the permissions or
46 * visibility. Do this by first removing then
47 * re-adding (if required) the file.
48 */
49 if (update)
50 sysfs_hash_and_remove(dir_sd, NULL,
51 (*attr)->name);
52 if (grp->is_visible) {
53 mode = grp->is_visible(kobj, *attr, i);
54 if (!mode)
55 continue;
56 }
57 error = sysfs_add_file_mode(dir_sd, *attr,
58 SYSFS_KOBJ_ATTR,
59 (*attr)->mode | mode);
60 if (unlikely(error))
61 break;
62 }
63 if (error) {
64 remove_files(dir_sd, kobj, grp);
65 goto exit;
66 }
67 }
37 68
38 /* in update mode, we're changing the permissions or 69 if (grp->bin_attrs) {
39 * visibility. Do this by first removing then 70 for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) {
40 * re-adding (if required) the file */ 71 if (update)
41 if (update) 72 sysfs_remove_bin_file(kobj, *bin_attr);
42 sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name); 73 error = sysfs_create_bin_file(kobj, *bin_attr);
43 if (grp->is_visible) { 74 if (error)
44 mode = grp->is_visible(kobj, *attr, i); 75 break;
45 if (!mode)
46 continue;
47 } 76 }
48 error = sysfs_add_file_mode(dir_sd, *attr, SYSFS_KOBJ_ATTR, 77 if (error)
49 (*attr)->mode | mode); 78 remove_files(dir_sd, kobj, grp);
50 if (unlikely(error))
51 break;
52 } 79 }
53 if (error) 80exit:
54 remove_files(dir_sd, kobj, grp);
55 return error; 81 return error;
56} 82}
57 83