xref: /openbmc/linux/include/linux/configfs.h (revision 77992f89)
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