blob: f9008be7a8a115119920e71df59e94d6149b23e7 [file] [log] [blame]
Thomas Gleixner328970d2019-05-24 12:04:05 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Joel Becker7063fbf2005-12-15 14:29:43 -08002/*
3 * vim: noexpandtab ts=8 sts=0 sw=8:
4 *
Joel Beckerecb3d282008-06-18 19:29:05 -07005 * configfs_example_macros.c - This file is a demonstration module
6 * containing a number of configfs subsystems. It uses the helper
7 * macros defined by configfs.h
Joel Becker7063fbf2005-12-15 14:29:43 -08008 *
Joel Becker7063fbf2005-12-15 14:29:43 -08009 * Based on sysfs:
Bartosz Golaszewski288f2952020-09-24 14:45:25 +020010 * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
Joel Becker7063fbf2005-12-15 14:29:43 -080011 *
12 * configfs Copyright (C) 2005 Oracle. All rights reserved.
13 */
14
15#include <linux/init.h>
Bartosz Golaszewskib86ff672020-09-24 14:45:21 +020016#include <linux/kernel.h>
Joel Becker7063fbf2005-12-15 14:29:43 -080017#include <linux/module.h>
18#include <linux/slab.h>
Joel Becker7063fbf2005-12-15 14:29:43 -080019#include <linux/configfs.h>
20
Joel Becker7063fbf2005-12-15 14:29:43 -080021/*
22 * 01-childless
23 *
24 * This first example is a childless subsystem. It cannot create
25 * any config_items. It just has attributes.
26 *
27 * Note that we are enclosing the configfs_subsystem inside a container.
28 * This is not necessary if a subsystem has no attributes directly
29 * on the subsystem. See the next example, 02-simple-children, for
30 * such a subsystem.
31 */
32
33struct childless {
34 struct configfs_subsystem subsys;
35 int showme;
36 int storeme;
37};
38
Joel Becker7063fbf2005-12-15 14:29:43 -080039static inline struct childless *to_childless(struct config_item *item)
40{
Bartosz Golaszewskie0ee1fd2020-09-24 14:45:18 +020041 return container_of(to_configfs_subsystem(to_config_group(item)),
42 struct childless, subsys);
Joel Becker7063fbf2005-12-15 14:29:43 -080043}
44
Christoph Hellwig51798222015-10-03 15:32:59 +020045static ssize_t childless_showme_show(struct config_item *item, char *page)
Joel Becker7063fbf2005-12-15 14:29:43 -080046{
Christoph Hellwig51798222015-10-03 15:32:59 +020047 struct childless *childless = to_childless(item);
Joel Becker7063fbf2005-12-15 14:29:43 -080048 ssize_t pos;
49
50 pos = sprintf(page, "%d\n", childless->showme);
51 childless->showme++;
52
53 return pos;
54}
55
Christoph Hellwig51798222015-10-03 15:32:59 +020056static ssize_t childless_storeme_show(struct config_item *item, char *page)
Joel Becker7063fbf2005-12-15 14:29:43 -080057{
Christoph Hellwig51798222015-10-03 15:32:59 +020058 return sprintf(page, "%d\n", to_childless(item)->storeme);
Joel Becker7063fbf2005-12-15 14:29:43 -080059}
60
Christoph Hellwig51798222015-10-03 15:32:59 +020061static ssize_t childless_storeme_store(struct config_item *item,
62 const char *page, size_t count)
Joel Becker7063fbf2005-12-15 14:29:43 -080063{
Christoph Hellwig51798222015-10-03 15:32:59 +020064 struct childless *childless = to_childless(item);
Bartosz Golaszewskib86ff672020-09-24 14:45:21 +020065 int ret;
Joel Becker7063fbf2005-12-15 14:29:43 -080066
Bartosz Golaszewskib86ff672020-09-24 14:45:21 +020067 ret = kstrtoint(page, 10, &childless->storeme);
68 if (ret)
69 return ret;
Joel Becker7063fbf2005-12-15 14:29:43 -080070
71 return count;
72}
73
Christoph Hellwig51798222015-10-03 15:32:59 +020074static ssize_t childless_description_show(struct config_item *item, char *page)
Joel Becker7063fbf2005-12-15 14:29:43 -080075{
76 return sprintf(page,
77"[01-childless]\n"
78"\n"
79"The childless subsystem is the simplest possible subsystem in\n"
80"configfs. It does not support the creation of child config_items.\n"
81"It only has a few attributes. In fact, it isn't much different\n"
82"than a directory in /proc.\n");
83}
84
Christoph Hellwig51798222015-10-03 15:32:59 +020085CONFIGFS_ATTR_RO(childless_, showme);
86CONFIGFS_ATTR(childless_, storeme);
87CONFIGFS_ATTR_RO(childless_, description);
Joel Becker7063fbf2005-12-15 14:29:43 -080088
89static struct configfs_attribute *childless_attrs[] = {
Christoph Hellwig51798222015-10-03 15:32:59 +020090 &childless_attr_showme,
91 &childless_attr_storeme,
92 &childless_attr_description,
Joel Becker7063fbf2005-12-15 14:29:43 -080093 NULL,
94};
95
Bhumika Goyal84c43672017-10-16 17:18:54 +020096static const struct config_item_type childless_type = {
Joel Becker7063fbf2005-12-15 14:29:43 -080097 .ct_attrs = childless_attrs,
98 .ct_owner = THIS_MODULE,
99};
100
101static struct childless childless_subsys = {
102 .subsys = {
103 .su_group = {
104 .cg_item = {
105 .ci_namebuf = "01-childless",
106 .ci_type = &childless_type,
107 },
108 },
109 },
110};
111
Joel Becker7063fbf2005-12-15 14:29:43 -0800112/* ----------------------------------------------------------------- */
113
114/*
115 * 02-simple-children
116 *
117 * This example merely has a simple one-attribute child. Note that
118 * there is no extra attribute structure, as the child's attribute is
119 * known from the get-go. Also, there is no container for the
120 * subsystem, as it has no attributes of its own.
121 */
122
123struct simple_child {
124 struct config_item item;
125 int storeme;
126};
127
128static inline struct simple_child *to_simple_child(struct config_item *item)
129{
Bartosz Golaszewskie0ee1fd2020-09-24 14:45:18 +0200130 return container_of(item, struct simple_child, item);
Joel Becker7063fbf2005-12-15 14:29:43 -0800131}
132
Christoph Hellwig51798222015-10-03 15:32:59 +0200133static ssize_t simple_child_storeme_show(struct config_item *item, char *page)
Joel Becker7063fbf2005-12-15 14:29:43 -0800134{
Christoph Hellwig51798222015-10-03 15:32:59 +0200135 return sprintf(page, "%d\n", to_simple_child(item)->storeme);
Joel Becker7063fbf2005-12-15 14:29:43 -0800136}
137
Christoph Hellwig51798222015-10-03 15:32:59 +0200138static ssize_t simple_child_storeme_store(struct config_item *item,
139 const char *page, size_t count)
Joel Becker7063fbf2005-12-15 14:29:43 -0800140{
141 struct simple_child *simple_child = to_simple_child(item);
Bartosz Golaszewskib86ff672020-09-24 14:45:21 +0200142 int ret;
Joel Becker7063fbf2005-12-15 14:29:43 -0800143
Bartosz Golaszewskib86ff672020-09-24 14:45:21 +0200144 ret = kstrtoint(page, 10, &simple_child->storeme);
145 if (ret)
146 return ret;
Joel Becker7063fbf2005-12-15 14:29:43 -0800147
148 return count;
149}
150
Christoph Hellwig51798222015-10-03 15:32:59 +0200151CONFIGFS_ATTR(simple_child_, storeme);
152
153static struct configfs_attribute *simple_child_attrs[] = {
154 &simple_child_attr_storeme,
155 NULL,
156};
157
Joel Becker7063fbf2005-12-15 14:29:43 -0800158static void simple_child_release(struct config_item *item)
159{
160 kfree(to_simple_child(item));
161}
162
163static struct configfs_item_operations simple_child_item_ops = {
Bartosz Golaszewski1b0d36e2020-09-24 14:45:20 +0200164 .release = simple_child_release,
Joel Becker7063fbf2005-12-15 14:29:43 -0800165};
166
Bhumika Goyal84c43672017-10-16 17:18:54 +0200167static const struct config_item_type simple_child_type = {
Joel Becker7063fbf2005-12-15 14:29:43 -0800168 .ct_item_ops = &simple_child_item_ops,
169 .ct_attrs = simple_child_attrs,
170 .ct_owner = THIS_MODULE,
171};
172
Joel Becker22dd0e82006-04-12 18:34:43 -0700173struct simple_children {
174 struct config_group group;
175};
176
177static inline struct simple_children *to_simple_children(struct config_item *item)
178{
Bartosz Golaszewskie0ee1fd2020-09-24 14:45:18 +0200179 return container_of(to_config_group(item),
180 struct simple_children, group);
Joel Becker22dd0e82006-04-12 18:34:43 -0700181}
182
Christoph Hellwig51798222015-10-03 15:32:59 +0200183static struct config_item *simple_children_make_item(struct config_group *group,
184 const char *name)
Joel Becker7063fbf2005-12-15 14:29:43 -0800185{
186 struct simple_child *simple_child;
187
Yoann Padioleaudd00cc42007-07-19 01:49:03 -0700188 simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
Joel Becker7063fbf2005-12-15 14:29:43 -0800189 if (!simple_child)
Joel Beckera6795e92008-07-17 15:21:29 -0700190 return ERR_PTR(-ENOMEM);
Joel Becker7063fbf2005-12-15 14:29:43 -0800191
Joel Becker7063fbf2005-12-15 14:29:43 -0800192 config_item_init_type_name(&simple_child->item, name,
193 &simple_child_type);
194
Joel Beckerf89ab862008-07-17 14:53:48 -0700195 return &simple_child->item;
Joel Becker7063fbf2005-12-15 14:29:43 -0800196}
197
Christoph Hellwig51798222015-10-03 15:32:59 +0200198static ssize_t simple_children_description_show(struct config_item *item,
199 char *page)
Joel Becker7063fbf2005-12-15 14:29:43 -0800200{
201 return sprintf(page,
202"[02-simple-children]\n"
203"\n"
204"This subsystem allows the creation of child config_items. These\n"
205"items have only one attribute that is readable and writeable.\n");
206}
207
Christoph Hellwig51798222015-10-03 15:32:59 +0200208CONFIGFS_ATTR_RO(simple_children_, description);
209
210static struct configfs_attribute *simple_children_attrs[] = {
211 &simple_children_attr_description,
212 NULL,
213};
214
Joel Becker22dd0e82006-04-12 18:34:43 -0700215static void simple_children_release(struct config_item *item)
216{
217 kfree(to_simple_children(item));
218}
219
Joel Becker7063fbf2005-12-15 14:29:43 -0800220static struct configfs_item_operations simple_children_item_ops = {
Joel Beckerecb3d282008-06-18 19:29:05 -0700221 .release = simple_children_release,
Joel Becker7063fbf2005-12-15 14:29:43 -0800222};
223
224/*
225 * Note that, since no extra work is required on ->drop_item(),
226 * no ->drop_item() is provided.
227 */
228static struct configfs_group_operations simple_children_group_ops = {
229 .make_item = simple_children_make_item,
230};
231
Bhumika Goyal84c43672017-10-16 17:18:54 +0200232static const struct config_item_type simple_children_type = {
Joel Becker7063fbf2005-12-15 14:29:43 -0800233 .ct_item_ops = &simple_children_item_ops,
234 .ct_group_ops = &simple_children_group_ops,
235 .ct_attrs = simple_children_attrs,
Joel Becker3d0f89b2006-01-25 13:31:07 -0800236 .ct_owner = THIS_MODULE,
Joel Becker7063fbf2005-12-15 14:29:43 -0800237};
238
239static struct configfs_subsystem simple_children_subsys = {
240 .su_group = {
241 .cg_item = {
242 .ci_namebuf = "02-simple-children",
243 .ci_type = &simple_children_type,
244 },
245 },
246};
247
Joel Becker7063fbf2005-12-15 14:29:43 -0800248/* ----------------------------------------------------------------- */
249
250/*
251 * 03-group-children
252 *
253 * This example reuses the simple_children group from above. However,
254 * the simple_children group is not the subsystem itself, it is a
255 * child of the subsystem. Creation of a group in the subsystem creates
256 * a new simple_children group. That group can then have simple_child
257 * children of its own.
258 */
259
Christoph Hellwig51798222015-10-03 15:32:59 +0200260static struct config_group *group_children_make_group(
261 struct config_group *group, const char *name)
Joel Becker7063fbf2005-12-15 14:29:43 -0800262{
263 struct simple_children *simple_children;
264
Yoann Padioleaudd00cc42007-07-19 01:49:03 -0700265 simple_children = kzalloc(sizeof(struct simple_children),
Joel Becker7063fbf2005-12-15 14:29:43 -0800266 GFP_KERNEL);
267 if (!simple_children)
Joel Beckera6795e92008-07-17 15:21:29 -0700268 return ERR_PTR(-ENOMEM);
Joel Becker7063fbf2005-12-15 14:29:43 -0800269
Joel Becker7063fbf2005-12-15 14:29:43 -0800270 config_group_init_type_name(&simple_children->group, name,
271 &simple_children_type);
272
Joel Beckerf89ab862008-07-17 14:53:48 -0700273 return &simple_children->group;
Joel Becker7063fbf2005-12-15 14:29:43 -0800274}
275
Christoph Hellwig51798222015-10-03 15:32:59 +0200276static ssize_t group_children_description_show(struct config_item *item,
277 char *page)
Joel Becker7063fbf2005-12-15 14:29:43 -0800278{
279 return sprintf(page,
280"[03-group-children]\n"
281"\n"
282"This subsystem allows the creation of child config_groups. These\n"
283"groups are like the subsystem simple-children.\n");
284}
285
Christoph Hellwig51798222015-10-03 15:32:59 +0200286CONFIGFS_ATTR_RO(group_children_, description);
287
288static struct configfs_attribute *group_children_attrs[] = {
289 &group_children_attr_description,
290 NULL,
Joel Becker7063fbf2005-12-15 14:29:43 -0800291};
292
293/*
294 * Note that, since no extra work is required on ->drop_item(),
295 * no ->drop_item() is provided.
296 */
297static struct configfs_group_operations group_children_group_ops = {
298 .make_group = group_children_make_group,
299};
300
Bhumika Goyal84c43672017-10-16 17:18:54 +0200301static const struct config_item_type group_children_type = {
Joel Becker7063fbf2005-12-15 14:29:43 -0800302 .ct_group_ops = &group_children_group_ops,
303 .ct_attrs = group_children_attrs,
Joel Becker3d0f89b2006-01-25 13:31:07 -0800304 .ct_owner = THIS_MODULE,
Joel Becker7063fbf2005-12-15 14:29:43 -0800305};
306
307static struct configfs_subsystem group_children_subsys = {
308 .su_group = {
309 .cg_item = {
310 .ci_namebuf = "03-group-children",
311 .ci_type = &group_children_type,
312 },
313 },
314};
315
316/* ----------------------------------------------------------------- */
317
318/*
319 * We're now done with our subsystem definitions.
320 * For convenience in this module, here's a list of them all. It
321 * allows the init function to easily register them. Most modules
322 * will only have one subsystem, and will only call register_subsystem
323 * on it directly.
324 */
325static struct configfs_subsystem *example_subsys[] = {
326 &childless_subsys.subsys,
327 &simple_children_subsys,
328 &group_children_subsys,
329 NULL,
330};
331
332static int __init configfs_example_init(void)
333{
Joel Becker7063fbf2005-12-15 14:29:43 -0800334 struct configfs_subsystem *subsys;
Bartosz Golaszewski4e415a82020-09-24 14:45:24 +0200335 int ret, i;
Joel Becker7063fbf2005-12-15 14:29:43 -0800336
337 for (i = 0; example_subsys[i]; i++) {
338 subsys = example_subsys[i];
339
340 config_group_init(&subsys->su_group);
Joel Beckere6bd07a2007-07-06 23:33:17 -0700341 mutex_init(&subsys->su_mutex);
Joel Becker7063fbf2005-12-15 14:29:43 -0800342 ret = configfs_register_subsystem(subsys);
343 if (ret) {
Bartosz Golaszewski76ecfcb082020-09-24 14:45:26 +0200344 pr_err("Error %d while registering subsystem %s\n",
345 ret, subsys->su_group.cg_item.ci_namebuf);
Joel Becker7063fbf2005-12-15 14:29:43 -0800346 goto out_unregister;
347 }
348 }
349
350 return 0;
351
352out_unregister:
Jiri Slabydcb3a082011-05-26 16:25:17 -0700353 for (i--; i >= 0; i--)
Joel Becker7063fbf2005-12-15 14:29:43 -0800354 configfs_unregister_subsystem(example_subsys[i]);
Joel Becker7063fbf2005-12-15 14:29:43 -0800355
356 return ret;
357}
358
359static void __exit configfs_example_exit(void)
360{
361 int i;
362
Jiri Slabydcb3a082011-05-26 16:25:17 -0700363 for (i = 0; example_subsys[i]; i++)
Joel Becker7063fbf2005-12-15 14:29:43 -0800364 configfs_unregister_subsystem(example_subsys[i]);
Joel Becker7063fbf2005-12-15 14:29:43 -0800365}
366
367module_init(configfs_example_init);
368module_exit(configfs_example_exit);
369MODULE_LICENSE("GPL");