Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : : /*
3 : : * sysfs.h - definitions for the device driver filesystem
4 : : *
5 : : * Copyright (c) 2001,2002 Patrick Mochel
6 : : * Copyright (c) 2004 Silicon Graphics, Inc.
7 : : * Copyright (c) 2007 SUSE Linux Products GmbH
8 : : * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
9 : : *
10 : : * Please see Documentation/filesystems/sysfs.txt for more information.
11 : : */
12 : :
13 : : #ifndef _SYSFS_H_
14 : : #define _SYSFS_H_
15 : :
16 : : #include <linux/kernfs.h>
17 : : #include <linux/compiler.h>
18 : : #include <linux/errno.h>
19 : : #include <linux/list.h>
20 : : #include <linux/lockdep.h>
21 : : #include <linux/kobject_ns.h>
22 : : #include <linux/stat.h>
23 : : #include <linux/atomic.h>
24 : :
25 : : struct kobject;
26 : : struct module;
27 : : struct bin_attribute;
28 : : enum kobj_ns_type;
29 : :
30 : : struct attribute {
31 : : const char *name;
32 : : umode_t mode;
33 : : #ifdef CONFIG_DEBUG_LOCK_ALLOC
34 : : bool ignore_lockdep:1;
35 : : struct lock_class_key *key;
36 : : struct lock_class_key skey;
37 : : #endif
38 : : };
39 : :
40 : : /**
41 : : * sysfs_attr_init - initialize a dynamically allocated sysfs attribute
42 : : * @attr: struct attribute to initialize
43 : : *
44 : : * Initialize a dynamically allocated struct attribute so we can
45 : : * make lockdep happy. This is a new requirement for attributes
46 : : * and initially this is only needed when lockdep is enabled.
47 : : * Lockdep gives a nice error when your attribute is added to
48 : : * sysfs if you don't have this.
49 : : */
50 : : #ifdef CONFIG_DEBUG_LOCK_ALLOC
51 : : #define sysfs_attr_init(attr) \
52 : : do { \
53 : : static struct lock_class_key __key; \
54 : : \
55 : : (attr)->key = &__key; \
56 : : } while (0)
57 : : #else
58 : : #define sysfs_attr_init(attr) do {} while (0)
59 : : #endif
60 : :
61 : : /**
62 : : * struct attribute_group - data structure used to declare an attribute group.
63 : : * @name: Optional: Attribute group name
64 : : * If specified, the attribute group will be created in
65 : : * a new subdirectory with this name.
66 : : * @is_visible: Optional: Function to return permissions associated with an
67 : : * attribute of the group. Will be called repeatedly for each
68 : : * non-binary attribute in the group. Only read/write
69 : : * permissions as well as SYSFS_PREALLOC are accepted. Must
70 : : * return 0 if an attribute is not visible. The returned value
71 : : * will replace static permissions defined in struct attribute.
72 : : * @is_bin_visible:
73 : : * Optional: Function to return permissions associated with a
74 : : * binary attribute of the group. Will be called repeatedly
75 : : * for each binary attribute in the group. Only read/write
76 : : * permissions as well as SYSFS_PREALLOC are accepted. Must
77 : : * return 0 if a binary attribute is not visible. The returned
78 : : * value will replace static permissions defined in
79 : : * struct bin_attribute.
80 : : * @attrs: Pointer to NULL terminated list of attributes.
81 : : * @bin_attrs: Pointer to NULL terminated list of binary attributes.
82 : : * Either attrs or bin_attrs or both must be provided.
83 : : */
84 : : struct attribute_group {
85 : : const char *name;
86 : : umode_t (*is_visible)(struct kobject *,
87 : : struct attribute *, int);
88 : : umode_t (*is_bin_visible)(struct kobject *,
89 : : struct bin_attribute *, int);
90 : : struct attribute **attrs;
91 : : struct bin_attribute **bin_attrs;
92 : : };
93 : :
94 : : /*
95 : : * Use these macros to make defining attributes easier.
96 : : * See include/linux/device.h for examples..
97 : : */
98 : :
99 : : #define SYSFS_PREALLOC 010000
100 : :
101 : : #define __ATTR(_name, _mode, _show, _store) { \
102 : : .attr = {.name = __stringify(_name), \
103 : : .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \
104 : : .show = _show, \
105 : : .store = _store, \
106 : : }
107 : :
108 : : #define __ATTR_PREALLOC(_name, _mode, _show, _store) { \
109 : : .attr = {.name = __stringify(_name), \
110 : : .mode = SYSFS_PREALLOC | VERIFY_OCTAL_PERMISSIONS(_mode) },\
111 : : .show = _show, \
112 : : .store = _store, \
113 : : }
114 : :
115 : : #define __ATTR_RO(_name) { \
116 : : .attr = { .name = __stringify(_name), .mode = 0444 }, \
117 : : .show = _name##_show, \
118 : : }
119 : :
120 : : #define __ATTR_RO_MODE(_name, _mode) { \
121 : : .attr = { .name = __stringify(_name), \
122 : : .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \
123 : : .show = _name##_show, \
124 : : }
125 : :
126 : : #define __ATTR_WO(_name) { \
127 : : .attr = { .name = __stringify(_name), .mode = 0200 }, \
128 : : .store = _name##_store, \
129 : : }
130 : :
131 : : #define __ATTR_RW(_name) __ATTR(_name, 0644, _name##_show, _name##_store)
132 : :
133 : : #define __ATTR_NULL { .attr = { .name = NULL } }
134 : :
135 : : #ifdef CONFIG_DEBUG_LOCK_ALLOC
136 : : #define __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) { \
137 : : .attr = {.name = __stringify(_name), .mode = _mode, \
138 : : .ignore_lockdep = true }, \
139 : : .show = _show, \
140 : : .store = _store, \
141 : : }
142 : : #else
143 : : #define __ATTR_IGNORE_LOCKDEP __ATTR
144 : : #endif
145 : :
146 : : #define __ATTRIBUTE_GROUPS(_name) \
147 : : static const struct attribute_group *_name##_groups[] = { \
148 : : &_name##_group, \
149 : : NULL, \
150 : : }
151 : :
152 : : #define ATTRIBUTE_GROUPS(_name) \
153 : : static const struct attribute_group _name##_group = { \
154 : : .attrs = _name##_attrs, \
155 : : }; \
156 : : __ATTRIBUTE_GROUPS(_name)
157 : :
158 : : struct file;
159 : : struct vm_area_struct;
160 : :
161 : : struct bin_attribute {
162 : : struct attribute attr;
163 : : size_t size;
164 : : void *private;
165 : : ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *,
166 : : char *, loff_t, size_t);
167 : : ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
168 : : char *, loff_t, size_t);
169 : : int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,
170 : : struct vm_area_struct *vma);
171 : : };
172 : :
173 : : /**
174 : : * sysfs_bin_attr_init - initialize a dynamically allocated bin_attribute
175 : : * @attr: struct bin_attribute to initialize
176 : : *
177 : : * Initialize a dynamically allocated struct bin_attribute so we
178 : : * can make lockdep happy. This is a new requirement for
179 : : * attributes and initially this is only needed when lockdep is
180 : : * enabled. Lockdep gives a nice error when your attribute is
181 : : * added to sysfs if you don't have this.
182 : : */
183 : : #define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr)
184 : :
185 : : /* macros to create static binary attributes easier */
186 : : #define __BIN_ATTR(_name, _mode, _read, _write, _size) { \
187 : : .attr = { .name = __stringify(_name), .mode = _mode }, \
188 : : .read = _read, \
189 : : .write = _write, \
190 : : .size = _size, \
191 : : }
192 : :
193 : : #define __BIN_ATTR_RO(_name, _size) { \
194 : : .attr = { .name = __stringify(_name), .mode = 0444 }, \
195 : : .read = _name##_read, \
196 : : .size = _size, \
197 : : }
198 : :
199 : : #define __BIN_ATTR_WO(_name, _size) { \
200 : : .attr = { .name = __stringify(_name), .mode = 0200 }, \
201 : : .write = _name##_write, \
202 : : .size = _size, \
203 : : }
204 : :
205 : : #define __BIN_ATTR_RW(_name, _size) \
206 : : __BIN_ATTR(_name, 0644, _name##_read, _name##_write, _size)
207 : :
208 : : #define __BIN_ATTR_NULL __ATTR_NULL
209 : :
210 : : #define BIN_ATTR(_name, _mode, _read, _write, _size) \
211 : : struct bin_attribute bin_attr_##_name = __BIN_ATTR(_name, _mode, _read, \
212 : : _write, _size)
213 : :
214 : : #define BIN_ATTR_RO(_name, _size) \
215 : : struct bin_attribute bin_attr_##_name = __BIN_ATTR_RO(_name, _size)
216 : :
217 : : #define BIN_ATTR_WO(_name, _size) \
218 : : struct bin_attribute bin_attr_##_name = __BIN_ATTR_WO(_name, _size)
219 : :
220 : : #define BIN_ATTR_RW(_name, _size) \
221 : : struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size)
222 : :
223 : : struct sysfs_ops {
224 : : ssize_t (*show)(struct kobject *, struct attribute *, char *);
225 : : ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
226 : : };
227 : :
228 : : #ifdef CONFIG_SYSFS
229 : :
230 : : int __must_check sysfs_create_dir_ns(struct kobject *kobj, const void *ns);
231 : : void sysfs_remove_dir(struct kobject *kobj);
232 : : int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
233 : : const void *new_ns);
234 : : int __must_check sysfs_move_dir_ns(struct kobject *kobj,
235 : : struct kobject *new_parent_kobj,
236 : : const void *new_ns);
237 : : int __must_check sysfs_create_mount_point(struct kobject *parent_kobj,
238 : : const char *name);
239 : : void sysfs_remove_mount_point(struct kobject *parent_kobj,
240 : : const char *name);
241 : :
242 : : int __must_check sysfs_create_file_ns(struct kobject *kobj,
243 : : const struct attribute *attr,
244 : : const void *ns);
245 : : int __must_check sysfs_create_files(struct kobject *kobj,
246 : : const struct attribute * const *attr);
247 : : int __must_check sysfs_chmod_file(struct kobject *kobj,
248 : : const struct attribute *attr, umode_t mode);
249 : : struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj,
250 : : const struct attribute *attr);
251 : : void sysfs_unbreak_active_protection(struct kernfs_node *kn);
252 : : void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
253 : : const void *ns);
254 : : bool sysfs_remove_file_self(struct kobject *kobj, const struct attribute *attr);
255 : : void sysfs_remove_files(struct kobject *kobj, const struct attribute * const *attr);
256 : :
257 : : int __must_check sysfs_create_bin_file(struct kobject *kobj,
258 : : const struct bin_attribute *attr);
259 : : void sysfs_remove_bin_file(struct kobject *kobj,
260 : : const struct bin_attribute *attr);
261 : :
262 : : int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target,
263 : : const char *name);
264 : : int __must_check sysfs_create_link_nowarn(struct kobject *kobj,
265 : : struct kobject *target,
266 : : const char *name);
267 : : void sysfs_remove_link(struct kobject *kobj, const char *name);
268 : :
269 : : int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *target,
270 : : const char *old_name, const char *new_name,
271 : : const void *new_ns);
272 : :
273 : : void sysfs_delete_link(struct kobject *dir, struct kobject *targ,
274 : : const char *name);
275 : :
276 : : int __must_check sysfs_create_group(struct kobject *kobj,
277 : : const struct attribute_group *grp);
278 : : int __must_check sysfs_create_groups(struct kobject *kobj,
279 : : const struct attribute_group **groups);
280 : : int __must_check sysfs_update_groups(struct kobject *kobj,
281 : : const struct attribute_group **groups);
282 : : int sysfs_update_group(struct kobject *kobj,
283 : : const struct attribute_group *grp);
284 : : void sysfs_remove_group(struct kobject *kobj,
285 : : const struct attribute_group *grp);
286 : : void sysfs_remove_groups(struct kobject *kobj,
287 : : const struct attribute_group **groups);
288 : : int sysfs_add_file_to_group(struct kobject *kobj,
289 : : const struct attribute *attr, const char *group);
290 : : void sysfs_remove_file_from_group(struct kobject *kobj,
291 : : const struct attribute *attr, const char *group);
292 : : int sysfs_merge_group(struct kobject *kobj,
293 : : const struct attribute_group *grp);
294 : : void sysfs_unmerge_group(struct kobject *kobj,
295 : : const struct attribute_group *grp);
296 : : int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name,
297 : : struct kobject *target, const char *link_name);
298 : : void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name,
299 : : const char *link_name);
300 : : int __compat_only_sysfs_link_entry_to_kobj(struct kobject *kobj,
301 : : struct kobject *target_kobj,
302 : : const char *target_name);
303 : :
304 : : void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
305 : :
306 : : int __must_check sysfs_init(void);
307 : :
308 : : static inline void sysfs_enable_ns(struct kernfs_node *kn)
309 : : {
310 : 2020 : return kernfs_enable_ns(kn);
311 : : }
312 : :
313 : : #else /* CONFIG_SYSFS */
314 : :
315 : : static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
316 : : {
317 : : return 0;
318 : : }
319 : :
320 : : static inline void sysfs_remove_dir(struct kobject *kobj)
321 : : {
322 : : }
323 : :
324 : : static inline int sysfs_rename_dir_ns(struct kobject *kobj,
325 : : const char *new_name, const void *new_ns)
326 : : {
327 : : return 0;
328 : : }
329 : :
330 : : static inline int sysfs_move_dir_ns(struct kobject *kobj,
331 : : struct kobject *new_parent_kobj,
332 : : const void *new_ns)
333 : : {
334 : : return 0;
335 : : }
336 : :
337 : : static inline int sysfs_create_mount_point(struct kobject *parent_kobj,
338 : : const char *name)
339 : : {
340 : : return 0;
341 : : }
342 : :
343 : : static inline void sysfs_remove_mount_point(struct kobject *parent_kobj,
344 : : const char *name)
345 : : {
346 : : }
347 : :
348 : : static inline int sysfs_create_file_ns(struct kobject *kobj,
349 : : const struct attribute *attr,
350 : : const void *ns)
351 : : {
352 : : return 0;
353 : : }
354 : :
355 : : static inline int sysfs_create_files(struct kobject *kobj,
356 : : const struct attribute * const *attr)
357 : : {
358 : : return 0;
359 : : }
360 : :
361 : : static inline int sysfs_chmod_file(struct kobject *kobj,
362 : : const struct attribute *attr, umode_t mode)
363 : : {
364 : : return 0;
365 : : }
366 : :
367 : : static inline struct kernfs_node *
368 : : sysfs_break_active_protection(struct kobject *kobj,
369 : : const struct attribute *attr)
370 : : {
371 : : return NULL;
372 : : }
373 : :
374 : : static inline void sysfs_unbreak_active_protection(struct kernfs_node *kn)
375 : : {
376 : : }
377 : :
378 : : static inline void sysfs_remove_file_ns(struct kobject *kobj,
379 : : const struct attribute *attr,
380 : : const void *ns)
381 : : {
382 : : }
383 : :
384 : : static inline bool sysfs_remove_file_self(struct kobject *kobj,
385 : : const struct attribute *attr)
386 : : {
387 : : return false;
388 : : }
389 : :
390 : : static inline void sysfs_remove_files(struct kobject *kobj,
391 : : const struct attribute * const *attr)
392 : : {
393 : : }
394 : :
395 : : static inline int sysfs_create_bin_file(struct kobject *kobj,
396 : : const struct bin_attribute *attr)
397 : : {
398 : : return 0;
399 : : }
400 : :
401 : : static inline void sysfs_remove_bin_file(struct kobject *kobj,
402 : : const struct bin_attribute *attr)
403 : : {
404 : : }
405 : :
406 : : static inline int sysfs_create_link(struct kobject *kobj,
407 : : struct kobject *target, const char *name)
408 : : {
409 : : return 0;
410 : : }
411 : :
412 : : static inline int sysfs_create_link_nowarn(struct kobject *kobj,
413 : : struct kobject *target,
414 : : const char *name)
415 : : {
416 : : return 0;
417 : : }
418 : :
419 : : static inline void sysfs_remove_link(struct kobject *kobj, const char *name)
420 : : {
421 : : }
422 : :
423 : : static inline int sysfs_rename_link_ns(struct kobject *k, struct kobject *t,
424 : : const char *old_name,
425 : : const char *new_name, const void *ns)
426 : : {
427 : : return 0;
428 : : }
429 : :
430 : : static inline void sysfs_delete_link(struct kobject *k, struct kobject *t,
431 : : const char *name)
432 : : {
433 : : }
434 : :
435 : : static inline int sysfs_create_group(struct kobject *kobj,
436 : : const struct attribute_group *grp)
437 : : {
438 : : return 0;
439 : : }
440 : :
441 : : static inline int sysfs_create_groups(struct kobject *kobj,
442 : : const struct attribute_group **groups)
443 : : {
444 : : return 0;
445 : : }
446 : :
447 : : static inline int sysfs_update_groups(struct kobject *kobj,
448 : : const struct attribute_group **groups)
449 : : {
450 : : return 0;
451 : : }
452 : :
453 : : static inline int sysfs_update_group(struct kobject *kobj,
454 : : const struct attribute_group *grp)
455 : : {
456 : : return 0;
457 : : }
458 : :
459 : : static inline void sysfs_remove_group(struct kobject *kobj,
460 : : const struct attribute_group *grp)
461 : : {
462 : : }
463 : :
464 : : static inline void sysfs_remove_groups(struct kobject *kobj,
465 : : const struct attribute_group **groups)
466 : : {
467 : : }
468 : :
469 : : static inline int sysfs_add_file_to_group(struct kobject *kobj,
470 : : const struct attribute *attr, const char *group)
471 : : {
472 : : return 0;
473 : : }
474 : :
475 : : static inline void sysfs_remove_file_from_group(struct kobject *kobj,
476 : : const struct attribute *attr, const char *group)
477 : : {
478 : : }
479 : :
480 : : static inline int sysfs_merge_group(struct kobject *kobj,
481 : : const struct attribute_group *grp)
482 : : {
483 : : return 0;
484 : : }
485 : :
486 : : static inline void sysfs_unmerge_group(struct kobject *kobj,
487 : : const struct attribute_group *grp)
488 : : {
489 : : }
490 : :
491 : : static inline int sysfs_add_link_to_group(struct kobject *kobj,
492 : : const char *group_name, struct kobject *target,
493 : : const char *link_name)
494 : : {
495 : : return 0;
496 : : }
497 : :
498 : : static inline void sysfs_remove_link_from_group(struct kobject *kobj,
499 : : const char *group_name, const char *link_name)
500 : : {
501 : : }
502 : :
503 : : static inline int __compat_only_sysfs_link_entry_to_kobj(
504 : : struct kobject *kobj,
505 : : struct kobject *target_kobj,
506 : : const char *target_name)
507 : : {
508 : : return 0;
509 : : }
510 : :
511 : : static inline void sysfs_notify(struct kobject *kobj, const char *dir,
512 : : const char *attr)
513 : : {
514 : : }
515 : :
516 : : static inline int __must_check sysfs_init(void)
517 : : {
518 : : return 0;
519 : : }
520 : :
521 : : static inline void sysfs_enable_ns(struct kernfs_node *kn)
522 : : {
523 : : }
524 : :
525 : : #endif /* CONFIG_SYSFS */
526 : :
527 : : static inline int __must_check sysfs_create_file(struct kobject *kobj,
528 : : const struct attribute *attr)
529 : : {
530 : 471876 : return sysfs_create_file_ns(kobj, attr, NULL);
531 : : }
532 : :
533 : : static inline void sysfs_remove_file(struct kobject *kobj,
534 : : const struct attribute *attr)
535 : : {
536 : 1620 : sysfs_remove_file_ns(kobj, attr, NULL);
537 : : }
538 : :
539 : : static inline int sysfs_rename_link(struct kobject *kobj, struct kobject *target,
540 : : const char *old_name, const char *new_name)
541 : : {
542 : : return sysfs_rename_link_ns(kobj, target, old_name, new_name, NULL);
543 : : }
544 : :
545 : : static inline void sysfs_notify_dirent(struct kernfs_node *kn)
546 : : {
547 : 0 : kernfs_notify(kn);
548 : : }
549 : :
550 : : static inline struct kernfs_node *sysfs_get_dirent(struct kernfs_node *parent,
551 : : const char *name)
552 : : {
553 : : return kernfs_find_and_get(parent, name);
554 : : }
555 : :
556 : : static inline struct kernfs_node *sysfs_get(struct kernfs_node *kn)
557 : : {
558 : 502586 : kernfs_get(kn);
559 : : return kn;
560 : : }
561 : :
562 : : static inline void sysfs_put(struct kernfs_node *kn)
563 : : {
564 : 414 : kernfs_put(kn);
565 : : }
566 : :
567 : : #endif /* _SYSFS_H_ */
|