aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/group.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs/group.c')
-rw-r--r--fs/sysfs/group.c70
1 files changed, 48 insertions, 22 deletions
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index aec3d5c98c94..09a1a25cd145 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
@@ -67,8 +93,8 @@ static int internal_create_group(struct kobject *kobj, int update,
67 /* Updates may happen before the object has been instantiated */ 93 /* Updates may happen before the object has been instantiated */
68 if (unlikely(update && !kobj->sd)) 94 if (unlikely(update && !kobj->sd))
69 return -EINVAL; 95 return -EINVAL;
70 if (!grp->attrs) { 96 if (!grp->attrs && !grp->bin_attrs) {
71 WARN(1, "sysfs: attrs not set by subsystem for group: %s/%s\n", 97 WARN(1, "sysfs: (bin_)attrs not set by subsystem for group: %s/%s\n",
72 kobj->name, grp->name ? "" : grp->name); 98 kobj->name, grp->name ? "" : grp->name);
73 return -EINVAL; 99 return -EINVAL;
74 } 100 }