diff options
Diffstat (limited to 'fs/sysfs/group.c')
-rw-r--r-- | fs/sysfs/group.c | 102 |
1 files changed, 53 insertions, 49 deletions
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 1898a10e38ce..6b579387c67a 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include "sysfs.h" | 18 | #include "sysfs.h" |
19 | 19 | ||
20 | 20 | ||
21 | static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | 21 | static void remove_files(struct kernfs_node *parent, struct kobject *kobj, |
22 | const struct attribute_group *grp) | 22 | const struct attribute_group *grp) |
23 | { | 23 | { |
24 | struct attribute *const *attr; | 24 | struct attribute *const *attr; |
@@ -26,13 +26,13 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | |||
26 | 26 | ||
27 | if (grp->attrs) | 27 | if (grp->attrs) |
28 | for (attr = grp->attrs; *attr; attr++) | 28 | for (attr = grp->attrs; *attr; attr++) |
29 | sysfs_hash_and_remove(dir_sd, (*attr)->name, NULL); | 29 | kernfs_remove_by_name(parent, (*attr)->name); |
30 | if (grp->bin_attrs) | 30 | if (grp->bin_attrs) |
31 | for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) | 31 | for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) |
32 | sysfs_remove_bin_file(kobj, *bin_attr); | 32 | sysfs_remove_bin_file(kobj, *bin_attr); |
33 | } | 33 | } |
34 | 34 | ||
35 | static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | 35 | static int create_files(struct kernfs_node *parent, struct kobject *kobj, |
36 | const struct attribute_group *grp, int update) | 36 | const struct attribute_group *grp, int update) |
37 | { | 37 | { |
38 | struct attribute *const *attr; | 38 | struct attribute *const *attr; |
@@ -49,22 +49,20 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | |||
49 | * re-adding (if required) the file. | 49 | * re-adding (if required) the file. |
50 | */ | 50 | */ |
51 | if (update) | 51 | if (update) |
52 | sysfs_hash_and_remove(dir_sd, (*attr)->name, | 52 | kernfs_remove_by_name(parent, (*attr)->name); |
53 | NULL); | ||
54 | if (grp->is_visible) { | 53 | if (grp->is_visible) { |
55 | mode = grp->is_visible(kobj, *attr, i); | 54 | mode = grp->is_visible(kobj, *attr, i); |
56 | if (!mode) | 55 | if (!mode) |
57 | continue; | 56 | continue; |
58 | } | 57 | } |
59 | error = sysfs_add_file_mode_ns(dir_sd, *attr, | 58 | error = sysfs_add_file_mode_ns(parent, *attr, false, |
60 | SYSFS_KOBJ_ATTR, | ||
61 | (*attr)->mode | mode, | 59 | (*attr)->mode | mode, |
62 | NULL); | 60 | NULL); |
63 | if (unlikely(error)) | 61 | if (unlikely(error)) |
64 | break; | 62 | break; |
65 | } | 63 | } |
66 | if (error) { | 64 | if (error) { |
67 | remove_files(dir_sd, kobj, grp); | 65 | remove_files(parent, kobj, grp); |
68 | goto exit; | 66 | goto exit; |
69 | } | 67 | } |
70 | } | 68 | } |
@@ -78,7 +76,7 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | |||
78 | break; | 76 | break; |
79 | } | 77 | } |
80 | if (error) | 78 | if (error) |
81 | remove_files(dir_sd, kobj, grp); | 79 | remove_files(parent, kobj, grp); |
82 | } | 80 | } |
83 | exit: | 81 | exit: |
84 | return error; | 82 | return error; |
@@ -88,7 +86,7 @@ exit: | |||
88 | static int internal_create_group(struct kobject *kobj, int update, | 86 | static int internal_create_group(struct kobject *kobj, int update, |
89 | const struct attribute_group *grp) | 87 | const struct attribute_group *grp) |
90 | { | 88 | { |
91 | struct sysfs_dirent *sd; | 89 | struct kernfs_node *kn; |
92 | int error; | 90 | int error; |
93 | 91 | ||
94 | BUG_ON(!kobj || (!update && !kobj->sd)); | 92 | BUG_ON(!kobj || (!update && !kobj->sd)); |
@@ -102,18 +100,22 @@ static int internal_create_group(struct kobject *kobj, int update, | |||
102 | return -EINVAL; | 100 | return -EINVAL; |
103 | } | 101 | } |
104 | if (grp->name) { | 102 | if (grp->name) { |
105 | error = sysfs_create_subdir(kobj, grp->name, &sd); | 103 | kn = kernfs_create_dir(kobj->sd, grp->name, |
106 | if (error) | 104 | S_IRWXU | S_IRUGO | S_IXUGO, kobj); |
107 | return error; | 105 | if (IS_ERR(kn)) { |
106 | if (PTR_ERR(kn) == -EEXIST) | ||
107 | sysfs_warn_dup(kobj->sd, grp->name); | ||
108 | return PTR_ERR(kn); | ||
109 | } | ||
108 | } else | 110 | } else |
109 | sd = kobj->sd; | 111 | kn = kobj->sd; |
110 | sysfs_get(sd); | 112 | kernfs_get(kn); |
111 | error = create_files(sd, kobj, grp, update); | 113 | error = create_files(kn, kobj, grp, update); |
112 | if (error) { | 114 | if (error) { |
113 | if (grp->name) | 115 | if (grp->name) |
114 | sysfs_remove(sd); | 116 | kernfs_remove(kn); |
115 | } | 117 | } |
116 | sysfs_put(sd); | 118 | kernfs_put(kn); |
117 | return error; | 119 | return error; |
118 | } | 120 | } |
119 | 121 | ||
@@ -203,25 +205,27 @@ EXPORT_SYMBOL_GPL(sysfs_update_group); | |||
203 | void sysfs_remove_group(struct kobject *kobj, | 205 | void sysfs_remove_group(struct kobject *kobj, |
204 | const struct attribute_group *grp) | 206 | const struct attribute_group *grp) |
205 | { | 207 | { |
206 | struct sysfs_dirent *dir_sd = kobj->sd; | 208 | struct kernfs_node *parent = kobj->sd; |
207 | struct sysfs_dirent *sd; | 209 | struct kernfs_node *kn; |
208 | 210 | ||
209 | if (grp->name) { | 211 | if (grp->name) { |
210 | sd = sysfs_get_dirent(dir_sd, grp->name); | 212 | kn = kernfs_find_and_get(parent, grp->name); |
211 | if (!sd) { | 213 | if (!kn) { |
212 | WARN(!sd, KERN_WARNING | 214 | WARN(!kn, KERN_WARNING |
213 | "sysfs group %p not found for kobject '%s'\n", | 215 | "sysfs group %p not found for kobject '%s'\n", |
214 | grp, kobject_name(kobj)); | 216 | grp, kobject_name(kobj)); |
215 | return; | 217 | return; |
216 | } | 218 | } |
217 | } else | 219 | } else { |
218 | sd = sysfs_get(dir_sd); | 220 | kn = parent; |
221 | kernfs_get(kn); | ||
222 | } | ||
219 | 223 | ||
220 | remove_files(sd, kobj, grp); | 224 | remove_files(kn, kobj, grp); |
221 | if (grp->name) | 225 | if (grp->name) |
222 | sysfs_remove(sd); | 226 | kernfs_remove(kn); |
223 | 227 | ||
224 | sysfs_put(sd); | 228 | kernfs_put(kn); |
225 | } | 229 | } |
226 | EXPORT_SYMBOL_GPL(sysfs_remove_group); | 230 | EXPORT_SYMBOL_GPL(sysfs_remove_group); |
227 | 231 | ||
@@ -257,22 +261,22 @@ EXPORT_SYMBOL_GPL(sysfs_remove_groups); | |||
257 | int sysfs_merge_group(struct kobject *kobj, | 261 | int sysfs_merge_group(struct kobject *kobj, |
258 | const struct attribute_group *grp) | 262 | const struct attribute_group *grp) |
259 | { | 263 | { |
260 | struct sysfs_dirent *dir_sd; | 264 | struct kernfs_node *parent; |
261 | int error = 0; | 265 | int error = 0; |
262 | struct attribute *const *attr; | 266 | struct attribute *const *attr; |
263 | int i; | 267 | int i; |
264 | 268 | ||
265 | dir_sd = sysfs_get_dirent(kobj->sd, grp->name); | 269 | parent = kernfs_find_and_get(kobj->sd, grp->name); |
266 | if (!dir_sd) | 270 | if (!parent) |
267 | return -ENOENT; | 271 | return -ENOENT; |
268 | 272 | ||
269 | for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr)) | 273 | for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr)) |
270 | error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR); | 274 | error = sysfs_add_file(parent, *attr, false); |
271 | if (error) { | 275 | if (error) { |
272 | while (--i >= 0) | 276 | while (--i >= 0) |
273 | sysfs_hash_and_remove(dir_sd, (*--attr)->name, NULL); | 277 | kernfs_remove_by_name(parent, (*--attr)->name); |
274 | } | 278 | } |
275 | sysfs_put(dir_sd); | 279 | kernfs_put(parent); |
276 | 280 | ||
277 | return error; | 281 | return error; |
278 | } | 282 | } |
@@ -286,14 +290,14 @@ EXPORT_SYMBOL_GPL(sysfs_merge_group); | |||
286 | void sysfs_unmerge_group(struct kobject *kobj, | 290 | void sysfs_unmerge_group(struct kobject *kobj, |
287 | const struct attribute_group *grp) | 291 | const struct attribute_group *grp) |
288 | { | 292 | { |
289 | struct sysfs_dirent *dir_sd; | 293 | struct kernfs_node *parent; |
290 | struct attribute *const *attr; | 294 | struct attribute *const *attr; |
291 | 295 | ||
292 | dir_sd = sysfs_get_dirent(kobj->sd, grp->name); | 296 | parent = kernfs_find_and_get(kobj->sd, grp->name); |
293 | if (dir_sd) { | 297 | if (parent) { |
294 | for (attr = grp->attrs; *attr; ++attr) | 298 | for (attr = grp->attrs; *attr; ++attr) |
295 | sysfs_hash_and_remove(dir_sd, (*attr)->name, NULL); | 299 | kernfs_remove_by_name(parent, (*attr)->name); |
296 | sysfs_put(dir_sd); | 300 | kernfs_put(parent); |
297 | } | 301 | } |
298 | } | 302 | } |
299 | EXPORT_SYMBOL_GPL(sysfs_unmerge_group); | 303 | EXPORT_SYMBOL_GPL(sysfs_unmerge_group); |
@@ -308,15 +312,15 @@ EXPORT_SYMBOL_GPL(sysfs_unmerge_group); | |||
308 | int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name, | 312 | int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name, |
309 | struct kobject *target, const char *link_name) | 313 | struct kobject *target, const char *link_name) |
310 | { | 314 | { |
311 | struct sysfs_dirent *dir_sd; | 315 | struct kernfs_node *parent; |
312 | int error = 0; | 316 | int error = 0; |
313 | 317 | ||
314 | dir_sd = sysfs_get_dirent(kobj->sd, group_name); | 318 | parent = kernfs_find_and_get(kobj->sd, group_name); |
315 | if (!dir_sd) | 319 | if (!parent) |
316 | return -ENOENT; | 320 | return -ENOENT; |
317 | 321 | ||
318 | error = sysfs_create_link_sd(dir_sd, target, link_name); | 322 | error = sysfs_create_link_sd(parent, target, link_name); |
319 | sysfs_put(dir_sd); | 323 | kernfs_put(parent); |
320 | 324 | ||
321 | return error; | 325 | return error; |
322 | } | 326 | } |
@@ -331,12 +335,12 @@ EXPORT_SYMBOL_GPL(sysfs_add_link_to_group); | |||
331 | void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name, | 335 | void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name, |
332 | const char *link_name) | 336 | const char *link_name) |
333 | { | 337 | { |
334 | struct sysfs_dirent *dir_sd; | 338 | struct kernfs_node *parent; |
335 | 339 | ||
336 | dir_sd = sysfs_get_dirent(kobj->sd, group_name); | 340 | parent = kernfs_find_and_get(kobj->sd, group_name); |
337 | if (dir_sd) { | 341 | if (parent) { |
338 | sysfs_hash_and_remove(dir_sd, link_name, NULL); | 342 | kernfs_remove_by_name(parent, link_name); |
339 | sysfs_put(dir_sd); | 343 | kernfs_put(parent); |
340 | } | 344 | } |
341 | } | 345 | } |
342 | EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group); | 346 | EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group); |