About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / filesystems / configfs / configfs_example_explicit.c


Based on kernel version 4.3. Page generated on 2015-11-02 12:49 EST.

1	/*
2	 * vim: noexpandtab ts=8 sts=0 sw=8:
3	 *
4	 * configfs_example_explicit.c - This file is a demonstration module
5	 *      containing a number of configfs subsystems.  It explicitly defines
6	 *      each structure without using the helper macros defined in
7	 *      configfs.h.
8	 *
9	 * This program is free software; you can redistribute it and/or
10	 * modify it under the terms of the GNU General Public
11	 * License as published by the Free Software Foundation; either
12	 * version 2 of the License, or (at your option) any later version.
13	 *
14	 * This program is distributed in the hope that it will be useful,
15	 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17	 * General Public License for more details.
18	 *
19	 * You should have received a copy of the GNU General Public
20	 * License along with this program; if not, write to the
21	 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22	 * Boston, MA 021110-1307, USA.
23	 *
24	 * Based on sysfs:
25	 * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
26	 *
27	 * configfs Copyright (C) 2005 Oracle.  All rights reserved.
28	 */
29	
30	#include <linux/init.h>
31	#include <linux/module.h>
32	#include <linux/slab.h>
33	
34	#include <linux/configfs.h>
35	
36	
37	
38	/*
39	 * 01-childless
40	 *
41	 * This first example is a childless subsystem.  It cannot create
42	 * any config_items.  It just has attributes.
43	 *
44	 * Note that we are enclosing the configfs_subsystem inside a container.
45	 * This is not necessary if a subsystem has no attributes directly
46	 * on the subsystem.  See the next example, 02-simple-children, for
47	 * such a subsystem.
48	 */
49	
50	struct childless {
51		struct configfs_subsystem subsys;
52		int showme;
53		int storeme;
54	};
55	
56	struct childless_attribute {
57		struct configfs_attribute attr;
58		ssize_t (*show)(struct childless *, char *);
59		ssize_t (*store)(struct childless *, const char *, size_t);
60	};
61	
62	static inline struct childless *to_childless(struct config_item *item)
63	{
64		return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
65	}
66	
67	static ssize_t childless_showme_read(struct childless *childless,
68					     char *page)
69	{
70		ssize_t pos;
71	
72		pos = sprintf(page, "%d\n", childless->showme);
73		childless->showme++;
74	
75		return pos;
76	}
77	
78	static ssize_t childless_storeme_read(struct childless *childless,
79					      char *page)
80	{
81		return sprintf(page, "%d\n", childless->storeme);
82	}
83	
84	static ssize_t childless_storeme_write(struct childless *childless,
85					       const char *page,
86					       size_t count)
87	{
88		unsigned long tmp;
89		char *p = (char *) page;
90	
91		tmp = simple_strtoul(p, &p, 10);
92		if ((*p != '\0') && (*p != '\n'))
93			return -EINVAL;
94	
95		if (tmp > INT_MAX)
96			return -ERANGE;
97	
98		childless->storeme = tmp;
99	
100		return count;
101	}
102	
103	static ssize_t childless_description_read(struct childless *childless,
104						  char *page)
105	{
106		return sprintf(page,
107	"[01-childless]\n"
108	"\n"
109	"The childless subsystem is the simplest possible subsystem in\n"
110	"configfs.  It does not support the creation of child config_items.\n"
111	"It only has a few attributes.  In fact, it isn't much different\n"
112	"than a directory in /proc.\n");
113	}
114	
115	static struct childless_attribute childless_attr_showme = {
116		.attr	= { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO },
117		.show	= childless_showme_read,
118	};
119	static struct childless_attribute childless_attr_storeme = {
120		.attr	= { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR },
121		.show	= childless_storeme_read,
122		.store	= childless_storeme_write,
123	};
124	static struct childless_attribute childless_attr_description = {
125		.attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO },
126		.show = childless_description_read,
127	};
128	
129	static struct configfs_attribute *childless_attrs[] = {
130		&childless_attr_showme.attr,
131		&childless_attr_storeme.attr,
132		&childless_attr_description.attr,
133		NULL,
134	};
135	
136	static ssize_t childless_attr_show(struct config_item *item,
137					   struct configfs_attribute *attr,
138					   char *page)
139	{
140		struct childless *childless = to_childless(item);
141		struct childless_attribute *childless_attr =
142			container_of(attr, struct childless_attribute, attr);
143		ssize_t ret = 0;
144	
145		if (childless_attr->show)
146			ret = childless_attr->show(childless, page);
147		return ret;
148	}
149	
150	static ssize_t childless_attr_store(struct config_item *item,
151					    struct configfs_attribute *attr,
152					    const char *page, size_t count)
153	{
154		struct childless *childless = to_childless(item);
155		struct childless_attribute *childless_attr =
156			container_of(attr, struct childless_attribute, attr);
157		ssize_t ret = -EINVAL;
158	
159		if (childless_attr->store)
160			ret = childless_attr->store(childless, page, count);
161		return ret;
162	}
163	
164	static struct configfs_item_operations childless_item_ops = {
165		.show_attribute		= childless_attr_show,
166		.store_attribute	= childless_attr_store,
167	};
168	
169	static struct config_item_type childless_type = {
170		.ct_item_ops	= &childless_item_ops,
171		.ct_attrs	= childless_attrs,
172		.ct_owner	= THIS_MODULE,
173	};
174	
175	static struct childless childless_subsys = {
176		.subsys = {
177			.su_group = {
178				.cg_item = {
179					.ci_namebuf = "01-childless",
180					.ci_type = &childless_type,
181				},
182			},
183		},
184	};
185	
186	
187	/* ----------------------------------------------------------------- */
188	
189	/*
190	 * 02-simple-children
191	 *
192	 * This example merely has a simple one-attribute child.  Note that
193	 * there is no extra attribute structure, as the child's attribute is
194	 * known from the get-go.  Also, there is no container for the
195	 * subsystem, as it has no attributes of its own.
196	 */
197	
198	struct simple_child {
199		struct config_item item;
200		int storeme;
201	};
202	
203	static inline struct simple_child *to_simple_child(struct config_item *item)
204	{
205		return item ? container_of(item, struct simple_child, item) : NULL;
206	}
207	
208	static struct configfs_attribute simple_child_attr_storeme = {
209		.ca_owner = THIS_MODULE,
210		.ca_name = "storeme",
211		.ca_mode = S_IRUGO | S_IWUSR,
212	};
213	
214	static struct configfs_attribute *simple_child_attrs[] = {
215		&simple_child_attr_storeme,
216		NULL,
217	};
218	
219	static ssize_t simple_child_attr_show(struct config_item *item,
220					      struct configfs_attribute *attr,
221					      char *page)
222	{
223		ssize_t count;
224		struct simple_child *simple_child = to_simple_child(item);
225	
226		count = sprintf(page, "%d\n", simple_child->storeme);
227	
228		return count;
229	}
230	
231	static ssize_t simple_child_attr_store(struct config_item *item,
232					       struct configfs_attribute *attr,
233					       const char *page, size_t count)
234	{
235		struct simple_child *simple_child = to_simple_child(item);
236		unsigned long tmp;
237		char *p = (char *) page;
238	
239		tmp = simple_strtoul(p, &p, 10);
240		if (!p || (*p && (*p != '\n')))
241			return -EINVAL;
242	
243		if (tmp > INT_MAX)
244			return -ERANGE;
245	
246		simple_child->storeme = tmp;
247	
248		return count;
249	}
250	
251	static void simple_child_release(struct config_item *item)
252	{
253		kfree(to_simple_child(item));
254	}
255	
256	static struct configfs_item_operations simple_child_item_ops = {
257		.release		= simple_child_release,
258		.show_attribute		= simple_child_attr_show,
259		.store_attribute	= simple_child_attr_store,
260	};
261	
262	static struct config_item_type simple_child_type = {
263		.ct_item_ops	= &simple_child_item_ops,
264		.ct_attrs	= simple_child_attrs,
265		.ct_owner	= THIS_MODULE,
266	};
267	
268	
269	struct simple_children {
270		struct config_group group;
271	};
272	
273	static inline struct simple_children *to_simple_children(struct config_item *item)
274	{
275		return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
276	}
277	
278	static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
279	{
280		struct simple_child *simple_child;
281	
282		simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
283		if (!simple_child)
284			return ERR_PTR(-ENOMEM);
285	
286		config_item_init_type_name(&simple_child->item, name,
287					   &simple_child_type);
288	
289		simple_child->storeme = 0;
290	
291		return &simple_child->item;
292	}
293	
294	static struct configfs_attribute simple_children_attr_description = {
295		.ca_owner = THIS_MODULE,
296		.ca_name = "description",
297		.ca_mode = S_IRUGO,
298	};
299	
300	static struct configfs_attribute *simple_children_attrs[] = {
301		&simple_children_attr_description,
302		NULL,
303	};
304	
305	static ssize_t simple_children_attr_show(struct config_item *item,
306						 struct configfs_attribute *attr,
307						 char *page)
308	{
309		return sprintf(page,
310	"[02-simple-children]\n"
311	"\n"
312	"This subsystem allows the creation of child config_items.  These\n"
313	"items have only one attribute that is readable and writeable.\n");
314	}
315	
316	static void simple_children_release(struct config_item *item)
317	{
318		kfree(to_simple_children(item));
319	}
320	
321	static struct configfs_item_operations simple_children_item_ops = {
322		.release	= simple_children_release,
323		.show_attribute	= simple_children_attr_show,
324	};
325	
326	/*
327	 * Note that, since no extra work is required on ->drop_item(),
328	 * no ->drop_item() is provided.
329	 */
330	static struct configfs_group_operations simple_children_group_ops = {
331		.make_item	= simple_children_make_item,
332	};
333	
334	static struct config_item_type simple_children_type = {
335		.ct_item_ops	= &simple_children_item_ops,
336		.ct_group_ops	= &simple_children_group_ops,
337		.ct_attrs	= simple_children_attrs,
338		.ct_owner	= THIS_MODULE,
339	};
340	
341	static struct configfs_subsystem simple_children_subsys = {
342		.su_group = {
343			.cg_item = {
344				.ci_namebuf = "02-simple-children",
345				.ci_type = &simple_children_type,
346			},
347		},
348	};
349	
350	
351	/* ----------------------------------------------------------------- */
352	
353	/*
354	 * 03-group-children
355	 *
356	 * This example reuses the simple_children group from above.  However,
357	 * the simple_children group is not the subsystem itself, it is a
358	 * child of the subsystem.  Creation of a group in the subsystem creates
359	 * a new simple_children group.  That group can then have simple_child
360	 * children of its own.
361	 */
362	
363	static struct config_group *group_children_make_group(struct config_group *group, const char *name)
364	{
365		struct simple_children *simple_children;
366	
367		simple_children = kzalloc(sizeof(struct simple_children),
368					  GFP_KERNEL);
369		if (!simple_children)
370			return ERR_PTR(-ENOMEM);
371	
372		config_group_init_type_name(&simple_children->group, name,
373					    &simple_children_type);
374	
375		return &simple_children->group;
376	}
377	
378	static struct configfs_attribute group_children_attr_description = {
379		.ca_owner = THIS_MODULE,
380		.ca_name = "description",
381		.ca_mode = S_IRUGO,
382	};
383	
384	static struct configfs_attribute *group_children_attrs[] = {
385		&group_children_attr_description,
386		NULL,
387	};
388	
389	static ssize_t group_children_attr_show(struct config_item *item,
390						struct configfs_attribute *attr,
391						char *page)
392	{
393		return sprintf(page,
394	"[03-group-children]\n"
395	"\n"
396	"This subsystem allows the creation of child config_groups.  These\n"
397	"groups are like the subsystem simple-children.\n");
398	}
399	
400	static struct configfs_item_operations group_children_item_ops = {
401		.show_attribute	= group_children_attr_show,
402	};
403	
404	/*
405	 * Note that, since no extra work is required on ->drop_item(),
406	 * no ->drop_item() is provided.
407	 */
408	static struct configfs_group_operations group_children_group_ops = {
409		.make_group	= group_children_make_group,
410	};
411	
412	static struct config_item_type group_children_type = {
413		.ct_item_ops	= &group_children_item_ops,
414		.ct_group_ops	= &group_children_group_ops,
415		.ct_attrs	= group_children_attrs,
416		.ct_owner	= THIS_MODULE,
417	};
418	
419	static struct configfs_subsystem group_children_subsys = {
420		.su_group = {
421			.cg_item = {
422				.ci_namebuf = "03-group-children",
423				.ci_type = &group_children_type,
424			},
425		},
426	};
427	
428	/* ----------------------------------------------------------------- */
429	
430	/*
431	 * We're now done with our subsystem definitions.
432	 * For convenience in this module, here's a list of them all.  It
433	 * allows the init function to easily register them.  Most modules
434	 * will only have one subsystem, and will only call register_subsystem
435	 * on it directly.
436	 */
437	static struct configfs_subsystem *example_subsys[] = {
438		&childless_subsys.subsys,
439		&simple_children_subsys,
440		&group_children_subsys,
441		NULL,
442	};
443	
444	static int __init configfs_example_init(void)
445	{
446		int ret;
447		int i;
448		struct configfs_subsystem *subsys;
449	
450		for (i = 0; example_subsys[i]; i++) {
451			subsys = example_subsys[i];
452	
453			config_group_init(&subsys->su_group);
454			mutex_init(&subsys->su_mutex);
455			ret = configfs_register_subsystem(subsys);
456			if (ret) {
457				printk(KERN_ERR "Error %d while registering subsystem %s\n",
458				       ret,
459				       subsys->su_group.cg_item.ci_namebuf);
460				goto out_unregister;
461			}
462		}
463	
464		return 0;
465	
466	out_unregister:
467		for (i--; i >= 0; i--)
468			configfs_unregister_subsystem(example_subsys[i]);
469	
470		return ret;
471	}
472	
473	static void __exit configfs_example_exit(void)
474	{
475		int i;
476	
477		for (i = 0; example_subsys[i]; i++)
478			configfs_unregister_subsystem(example_subsys[i]);
479	}
480	
481	module_init(configfs_example_init);
482	module_exit(configfs_example_exit);
483	MODULE_LICENSE("GPL");
Hide Line Numbers


About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog