diff options
Diffstat (limited to 'fs/sysfs/group.c')
-rw-r--r-- | fs/sysfs/group.c | 70 |
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 | ||
29 | static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | 33 | static 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) | 80 | exit: |
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 | } |