1328970deSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2*fa60ce2cSMasahiro Yamada /*
37063fbf2SJoel Becker * configfs.h - definitions for the device driver filesystem
47063fbf2SJoel Becker *
57063fbf2SJoel Becker * Based on sysfs:
67063fbf2SJoel Becker * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
77063fbf2SJoel Becker *
87063fbf2SJoel Becker * Based on kobject.h:
97063fbf2SJoel Becker * Copyright (c) 2002-2003 Patrick Mochel
107063fbf2SJoel Becker * Copyright (c) 2002-2003 Open Source Development Labs
117063fbf2SJoel Becker *
127063fbf2SJoel Becker * configfs Copyright (C) 2005 Oracle. All rights reserved.
137063fbf2SJoel Becker *
1498264991SMauro Carvalho Chehab * Please read Documentation/filesystems/configfs.rst before using
1555dff495SRandy Dunlap * the configfs interface, ESPECIALLY the parts about reference counts and
167063fbf2SJoel Becker * item destructors.
177063fbf2SJoel Becker */
187063fbf2SJoel Becker
197063fbf2SJoel Becker #ifndef _CONFIGFS_H_
207063fbf2SJoel Becker #define _CONFIGFS_H_
217063fbf2SJoel Becker
22a6ab5374SBart Van Assche #include <linux/stat.h> /* S_IRUGO */
23a6ab5374SBart Van Assche #include <linux/types.h> /* ssize_t */
24a6ab5374SBart Van Assche #include <linux/list.h> /* struct list_head */
25a6ab5374SBart Van Assche #include <linux/kref.h> /* struct kref */
26a6ab5374SBart Van Assche #include <linux/mutex.h> /* struct mutex */
277063fbf2SJoel Becker
287063fbf2SJoel Becker #define CONFIGFS_ITEM_NAME_LEN 20
297063fbf2SJoel Becker
307063fbf2SJoel Becker struct module;
317063fbf2SJoel Becker
327063fbf2SJoel Becker struct configfs_item_operations;
337063fbf2SJoel Becker struct configfs_group_operations;
347063fbf2SJoel Becker struct configfs_attribute;
3503607aceSPantelis Antoniou struct configfs_bin_attribute;
367063fbf2SJoel Becker struct configfs_subsystem;
377063fbf2SJoel Becker
387063fbf2SJoel Becker struct config_item {
397063fbf2SJoel Becker char *ci_name;
407063fbf2SJoel Becker char ci_namebuf[CONFIGFS_ITEM_NAME_LEN];
417063fbf2SJoel Becker struct kref ci_kref;
427063fbf2SJoel Becker struct list_head ci_entry;
437063fbf2SJoel Becker struct config_item *ci_parent;
447063fbf2SJoel Becker struct config_group *ci_group;
45aa293583SBhumika Goyal const struct config_item_type *ci_type;
467063fbf2SJoel Becker struct dentry *ci_dentry;
477063fbf2SJoel Becker };
487063fbf2SJoel Becker
498db14860SNicolas Iooss extern __printf(2, 3)
508db14860SNicolas Iooss int config_item_set_name(struct config_item *, const char *, ...);
517063fbf2SJoel Becker
config_item_name(struct config_item * item)527063fbf2SJoel Becker static inline char *config_item_name(struct config_item * item)
537063fbf2SJoel Becker {
547063fbf2SJoel Becker return item->ci_name;
557063fbf2SJoel Becker }
567063fbf2SJoel Becker
577063fbf2SJoel Becker extern void config_item_init_type_name(struct config_item *item,
587063fbf2SJoel Becker const char *name,
59aa293583SBhumika Goyal const struct config_item_type *type);
607063fbf2SJoel Becker
617063fbf2SJoel Becker extern struct config_item *config_item_get(struct config_item *);
6219e72d3aSBart Van Assche extern struct config_item *config_item_get_unless_zero(struct config_item *);
637063fbf2SJoel Becker extern void config_item_put(struct config_item *);
647063fbf2SJoel Becker
657063fbf2SJoel Becker struct config_item_type {
667063fbf2SJoel Becker struct module *ct_owner;
677063fbf2SJoel Becker struct configfs_item_operations *ct_item_ops;
687063fbf2SJoel Becker struct configfs_group_operations *ct_group_ops;
697063fbf2SJoel Becker struct configfs_attribute **ct_attrs;
7003607aceSPantelis Antoniou struct configfs_bin_attribute **ct_bin_attrs;
717063fbf2SJoel Becker };
727063fbf2SJoel Becker
737063fbf2SJoel Becker /**
747063fbf2SJoel Becker * group - a group of config_items of a specific type, belonging
757063fbf2SJoel Becker * to a specific subsystem.
767063fbf2SJoel Becker */
777063fbf2SJoel Becker struct config_group {
787063fbf2SJoel Becker struct config_item cg_item;
797063fbf2SJoel Becker struct list_head cg_children;
807063fbf2SJoel Becker struct configfs_subsystem *cg_subsys;
811ae1602dSChristoph Hellwig struct list_head default_groups;
821ae1602dSChristoph Hellwig struct list_head group_entry;
837063fbf2SJoel Becker };
847063fbf2SJoel Becker
857063fbf2SJoel Becker extern void config_group_init(struct config_group *group);
867063fbf2SJoel Becker extern void config_group_init_type_name(struct config_group *group,
877063fbf2SJoel Becker const char *name,
88aa293583SBhumika Goyal const struct config_item_type *type);
897063fbf2SJoel Becker
to_config_group(struct config_item * item)907063fbf2SJoel Becker static inline struct config_group *to_config_group(struct config_item *item)
917063fbf2SJoel Becker {
927063fbf2SJoel Becker return item ? container_of(item,struct config_group,cg_item) : NULL;
937063fbf2SJoel Becker }
947063fbf2SJoel Becker
config_group_get(struct config_group * group)957063fbf2SJoel Becker static inline struct config_group *config_group_get(struct config_group *group)
967063fbf2SJoel Becker {
977063fbf2SJoel Becker return group ? to_config_group(config_item_get(&group->cg_item)) : NULL;
987063fbf2SJoel Becker }
997063fbf2SJoel Becker
config_group_put(struct config_group * group)1007063fbf2SJoel Becker static inline void config_group_put(struct config_group *group)
1017063fbf2SJoel Becker {
1027063fbf2SJoel Becker config_item_put(&group->cg_item);
1037063fbf2SJoel Becker }
1047063fbf2SJoel Becker
1053fe6c5ceSSatyam Sharma extern struct config_item *config_group_find_item(struct config_group *,
1063fe6c5ceSSatyam Sharma const char *);
1077063fbf2SJoel Becker
1087063fbf2SJoel Becker
configfs_add_default_group(struct config_group * new_group,struct config_group * group)1091ae1602dSChristoph Hellwig static inline void configfs_add_default_group(struct config_group *new_group,
1101ae1602dSChristoph Hellwig struct config_group *group)
1111ae1602dSChristoph Hellwig {
1121ae1602dSChristoph Hellwig list_add_tail(&new_group->group_entry, &group->default_groups);
1131ae1602dSChristoph Hellwig }
1141ae1602dSChristoph Hellwig
1157063fbf2SJoel Becker struct configfs_attribute {
1163d0f89bbSJoel Becker const char *ca_name;
1177063fbf2SJoel Becker struct module *ca_owner;
11843947514SAl Viro umode_t ca_mode;
119870823e6SChristoph Hellwig ssize_t (*show)(struct config_item *, char *);
120870823e6SChristoph Hellwig ssize_t (*store)(struct config_item *, const char *, size_t);
1217063fbf2SJoel Becker };
1227063fbf2SJoel Becker
123870823e6SChristoph Hellwig #define CONFIGFS_ATTR(_pfx, _name) \
124870823e6SChristoph Hellwig static struct configfs_attribute _pfx##attr_##_name = { \
125870823e6SChristoph Hellwig .ca_name = __stringify(_name), \
126870823e6SChristoph Hellwig .ca_mode = S_IRUGO | S_IWUSR, \
127870823e6SChristoph Hellwig .ca_owner = THIS_MODULE, \
128870823e6SChristoph Hellwig .show = _pfx##_name##_show, \
129870823e6SChristoph Hellwig .store = _pfx##_name##_store, \
130870823e6SChristoph Hellwig }
131870823e6SChristoph Hellwig
132870823e6SChristoph Hellwig #define CONFIGFS_ATTR_RO(_pfx, _name) \
133870823e6SChristoph Hellwig static struct configfs_attribute _pfx##attr_##_name = { \
134870823e6SChristoph Hellwig .ca_name = __stringify(_name), \
135870823e6SChristoph Hellwig .ca_mode = S_IRUGO, \
136870823e6SChristoph Hellwig .ca_owner = THIS_MODULE, \
137870823e6SChristoph Hellwig .show = _pfx##_name##_show, \
138870823e6SChristoph Hellwig }
139870823e6SChristoph Hellwig
140870823e6SChristoph Hellwig #define CONFIGFS_ATTR_WO(_pfx, _name) \
141870823e6SChristoph Hellwig static struct configfs_attribute _pfx##attr_##_name = { \
142870823e6SChristoph Hellwig .ca_name = __stringify(_name), \
143870823e6SChristoph Hellwig .ca_mode = S_IWUSR, \
144870823e6SChristoph Hellwig .ca_owner = THIS_MODULE, \
145870823e6SChristoph Hellwig .store = _pfx##_name##_store, \
146870823e6SChristoph Hellwig }
147870823e6SChristoph Hellwig
14803607aceSPantelis Antoniou struct file;
14903607aceSPantelis Antoniou struct vm_area_struct;
15003607aceSPantelis Antoniou
15103607aceSPantelis Antoniou struct configfs_bin_attribute {
15203607aceSPantelis Antoniou struct configfs_attribute cb_attr; /* std. attribute */
15303607aceSPantelis Antoniou void *cb_private; /* for user */
15403607aceSPantelis Antoniou size_t cb_max_size; /* max core size */
15503607aceSPantelis Antoniou ssize_t (*read)(struct config_item *, void *, size_t);
15603607aceSPantelis Antoniou ssize_t (*write)(struct config_item *, const void *, size_t);
15703607aceSPantelis Antoniou };
15803607aceSPantelis Antoniou
15903607aceSPantelis Antoniou #define CONFIGFS_BIN_ATTR(_pfx, _name, _priv, _maxsz) \
16003607aceSPantelis Antoniou static struct configfs_bin_attribute _pfx##attr_##_name = { \
16103607aceSPantelis Antoniou .cb_attr = { \
16203607aceSPantelis Antoniou .ca_name = __stringify(_name), \
16303607aceSPantelis Antoniou .ca_mode = S_IRUGO | S_IWUSR, \
16403607aceSPantelis Antoniou .ca_owner = THIS_MODULE, \
16503607aceSPantelis Antoniou }, \
16603607aceSPantelis Antoniou .cb_private = _priv, \
16703607aceSPantelis Antoniou .cb_max_size = _maxsz, \
16803607aceSPantelis Antoniou .read = _pfx##_name##_read, \
16903607aceSPantelis Antoniou .write = _pfx##_name##_write, \
17003607aceSPantelis Antoniou }
17103607aceSPantelis Antoniou
17203607aceSPantelis Antoniou #define CONFIGFS_BIN_ATTR_RO(_pfx, _name, _priv, _maxsz) \
17396c22a32SOctavian Purdila static struct configfs_bin_attribute _pfx##attr_##_name = { \
17403607aceSPantelis Antoniou .cb_attr = { \
17503607aceSPantelis Antoniou .ca_name = __stringify(_name), \
17603607aceSPantelis Antoniou .ca_mode = S_IRUGO, \
17703607aceSPantelis Antoniou .ca_owner = THIS_MODULE, \
17803607aceSPantelis Antoniou }, \
17903607aceSPantelis Antoniou .cb_private = _priv, \
18003607aceSPantelis Antoniou .cb_max_size = _maxsz, \
18103607aceSPantelis Antoniou .read = _pfx##_name##_read, \
18203607aceSPantelis Antoniou }
18303607aceSPantelis Antoniou
18403607aceSPantelis Antoniou #define CONFIGFS_BIN_ATTR_WO(_pfx, _name, _priv, _maxsz) \
18596c22a32SOctavian Purdila static struct configfs_bin_attribute _pfx##attr_##_name = { \
18603607aceSPantelis Antoniou .cb_attr = { \
18703607aceSPantelis Antoniou .ca_name = __stringify(_name), \
18803607aceSPantelis Antoniou .ca_mode = S_IWUSR, \
18903607aceSPantelis Antoniou .ca_owner = THIS_MODULE, \
19003607aceSPantelis Antoniou }, \
19103607aceSPantelis Antoniou .cb_private = _priv, \
19203607aceSPantelis Antoniou .cb_max_size = _maxsz, \
19303607aceSPantelis Antoniou .write = _pfx##_name##_write, \
19403607aceSPantelis Antoniou }
19503607aceSPantelis Antoniou
1969b1d9aa4SSatyam Sharma /*
1977063fbf2SJoel Becker * If allow_link() exists, the item can symlink(2) out to other
1987063fbf2SJoel Becker * items. If the item is a group, it may support mkdir(2).
1997063fbf2SJoel Becker * Groups supply one of make_group() and make_item(). If the
2007063fbf2SJoel Becker * group supports make_group(), one can create group children. If it
201a6795e9eSJoel Becker * supports make_item(), one can create config_item children. make_group()
202a6795e9eSJoel Becker * and make_item() return ERR_PTR() on errors. If it has
2037063fbf2SJoel Becker * default_groups on group->default_groups, it has automatically created
2047063fbf2SJoel Becker * group children. default_groups may coexist alongsize make_group() or
2057063fbf2SJoel Becker * make_item(), but if the group wishes to have only default_groups
2067063fbf2SJoel Becker * children (disallowing mkdir(2)), it need not provide either function.
2077063fbf2SJoel Becker */
2087063fbf2SJoel Becker struct configfs_item_operations {
2097063fbf2SJoel Becker void (*release)(struct config_item *);
2107063fbf2SJoel Becker int (*allow_link)(struct config_item *src, struct config_item *target);
211e16769d4SAndrzej Pietrasiewicz void (*drop_link)(struct config_item *src, struct config_item *target);
2127063fbf2SJoel Becker };
2137063fbf2SJoel Becker
2147063fbf2SJoel Becker struct configfs_group_operations {
215f89ab861SJoel Becker struct config_item *(*make_item)(struct config_group *group, const char *name);
216f89ab861SJoel Becker struct config_group *(*make_group)(struct config_group *group, const char *name);
217299894ccSJoel Becker void (*disconnect_notify)(struct config_group *group, struct config_item *item);
2187063fbf2SJoel Becker void (*drop_item)(struct config_group *group, struct config_item *item);
2197063fbf2SJoel Becker };
2207063fbf2SJoel Becker
2217063fbf2SJoel Becker struct configfs_subsystem {
2227063fbf2SJoel Becker struct config_group su_group;
223e6bd07aeSJoel Becker struct mutex su_mutex;
2247063fbf2SJoel Becker };
2257063fbf2SJoel Becker
to_configfs_subsystem(struct config_group * group)2267063fbf2SJoel Becker static inline struct configfs_subsystem *to_configfs_subsystem(struct config_group *group)
2277063fbf2SJoel Becker {
2287063fbf2SJoel Becker return group ?
2297063fbf2SJoel Becker container_of(group, struct configfs_subsystem, su_group) :
2307063fbf2SJoel Becker NULL;
2317063fbf2SJoel Becker }
2327063fbf2SJoel Becker
2337063fbf2SJoel Becker int configfs_register_subsystem(struct configfs_subsystem *subsys);
2347063fbf2SJoel Becker void configfs_unregister_subsystem(struct configfs_subsystem *subsys);
2357063fbf2SJoel Becker
2365cf6a51eSDaniel Baluta int configfs_register_group(struct config_group *parent_group,
2375cf6a51eSDaniel Baluta struct config_group *group);
2385cf6a51eSDaniel Baluta void configfs_unregister_group(struct config_group *group);
2395cf6a51eSDaniel Baluta
2401ae1602dSChristoph Hellwig void configfs_remove_default_groups(struct config_group *group);
2411ae1602dSChristoph Hellwig
2425cf6a51eSDaniel Baluta struct config_group *
2435cf6a51eSDaniel Baluta configfs_register_default_group(struct config_group *parent_group,
2445cf6a51eSDaniel Baluta const char *name,
245aa293583SBhumika Goyal const struct config_item_type *item_type);
2465cf6a51eSDaniel Baluta void configfs_unregister_default_group(struct config_group *group);
2475cf6a51eSDaniel Baluta
248631d1febSJoel Becker /* These functions can sleep and can alloc with GFP_KERNEL */
249631d1febSJoel Becker /* WARNING: These cannot be called underneath configfs callbacks!! */
2509a9e3415SKrzysztof Opasiak int configfs_depend_item(struct configfs_subsystem *subsys,
2519a9e3415SKrzysztof Opasiak struct config_item *target);
2529a9e3415SKrzysztof Opasiak void configfs_undepend_item(struct config_item *target);
253631d1febSJoel Becker
254d79d75b5SKrzysztof Opasiak /*
255d79d75b5SKrzysztof Opasiak * These functions can sleep and can alloc with GFP_KERNEL
256d79d75b5SKrzysztof Opasiak * NOTE: These should be called only underneath configfs callbacks.
257d79d75b5SKrzysztof Opasiak * NOTE: First parameter is a caller's subsystem, not target's.
258d79d75b5SKrzysztof Opasiak * WARNING: These cannot be called on newly created item
259d79d75b5SKrzysztof Opasiak * (in make_group()/make_item() callback)
260d79d75b5SKrzysztof Opasiak */
261d79d75b5SKrzysztof Opasiak int configfs_depend_item_unlocked(struct configfs_subsystem *caller_subsys,
262d79d75b5SKrzysztof Opasiak struct config_item *target);
263d79d75b5SKrzysztof Opasiak
264d79d75b5SKrzysztof Opasiak
configfs_undepend_item_unlocked(struct config_item * target)265d79d75b5SKrzysztof Opasiak static inline void configfs_undepend_item_unlocked(struct config_item *target)
266d79d75b5SKrzysztof Opasiak {
267d79d75b5SKrzysztof Opasiak configfs_undepend_item(target);
268d79d75b5SKrzysztof Opasiak }
2697063fbf2SJoel Becker
2707063fbf2SJoel Becker #endif /* _CONFIGFS_H_ */
271