diff options
-rw-r--r-- | fs/sysfs/group.c | 66 | ||||
-rw-r--r-- | include/linux/sysfs.h | 4 |
2 files changed, 48 insertions, 22 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 | ||
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 | ||
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index d50a96b9bb6d..2c3b6a30697d 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | struct kobject; | 22 | struct kobject; |
23 | struct module; | 23 | struct module; |
24 | struct bin_attribute; | ||
24 | enum kobj_ns_type; | 25 | enum kobj_ns_type; |
25 | 26 | ||
26 | struct attribute { | 27 | struct attribute { |
@@ -59,10 +60,9 @@ struct attribute_group { | |||
59 | umode_t (*is_visible)(struct kobject *, | 60 | umode_t (*is_visible)(struct kobject *, |
60 | struct attribute *, int); | 61 | struct attribute *, int); |
61 | struct attribute **attrs; | 62 | struct attribute **attrs; |
63 | struct bin_attribute **bin_attrs; | ||
62 | }; | 64 | }; |
63 | 65 | ||
64 | |||
65 | |||
66 | /** | 66 | /** |
67 | * Use these macros to make defining attributes easier. See include/linux/device.h | 67 | * Use these macros to make defining attributes easier. See include/linux/device.h |
68 | * for examples.. | 68 | * for examples.. |