aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/filesystems
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-13 23:04:17 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-13 23:04:17 -0500
commit9aa3d651a9199103eb6451aeb0ac1b66a6d770a6 (patch)
tree42cc631c54e1fcbdeedee8e955c4797634a91af7 /Documentation/filesystems
parent5d2eb548b309be34ecf3b91f0b7300a2b9d09b8c (diff)
parent517982229f78b2aebf00a8a337e84e8eeea70b8e (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target updates from Nicholas Bellinger: "This series contains HCH's changes to absorb configfs attribute ->show() + ->store() function pointer usage from it's original tree-wide consumers, into common configfs code. It includes usb-gadget, target w/ drivers, netconsole and ocfs2 changes to realize the improved simplicity, that now renders the original include/target/configfs_macros.h CPP magic for fabric drivers and others, unnecessary and obsolete. And with common code in place, new configfs attributes can be added easier than ever before. Note, there are further improvements in-flight from other folks for v4.5 code in configfs land, plus number of target fixes for post -rc1 code" In the meantime, a new user of the now-removed old configfs API came in through the char/misc tree in commit 7bd1d4093c2f ("stm class: Introduce an abstraction for System Trace Module devices"). This merge resolution comes from Alexander Shishkin, who updated his stm class tracing abstraction to account for the removal of the old show_attribute and store_attribute methods in commit 517982229f78 ("configfs: remove old API") from this pull. As Alexander says about that patch: "There's no need to keep an extra wrapper structure per item and the awkward show_attribute/store_attribute item ops are no longer needed. This patch converts policy code to the new api, all the while making the code quite a bit smaller and easier on the eyes. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>" That patch was folded into the merge so that the tree should be fully bisectable. * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (23 commits) configfs: remove old API ocfs2/cluster: use per-attribute show and store methods ocfs2/cluster: move locking into attribute store methods netconsole: use per-attribute show and store methods target: use per-attribute show and store methods spear13xx_pcie_gadget: use per-attribute show and store methods dlm: use per-attribute show and store methods usb-gadget/f_serial: use per-attribute show and store methods usb-gadget/f_phonet: use per-attribute show and store methods usb-gadget/f_obex: use per-attribute show and store methods usb-gadget/f_uac2: use per-attribute show and store methods usb-gadget/f_uac1: use per-attribute show and store methods usb-gadget/f_mass_storage: use per-attribute show and store methods usb-gadget/f_sourcesink: use per-attribute show and store methods usb-gadget/f_printer: use per-attribute show and store methods usb-gadget/f_midi: use per-attribute show and store methods usb-gadget/f_loopback: use per-attribute show and store methods usb-gadget/ether: use per-attribute show and store methods usb-gadget/f_acm: use per-attribute show and store methods usb-gadget/f_hid: use per-attribute show and store methods ...
Diffstat (limited to 'Documentation/filesystems')
-rw-r--r--Documentation/filesystems/Makefile2
-rw-r--r--Documentation/filesystems/configfs/Makefile3
-rw-r--r--Documentation/filesystems/configfs/configfs.txt38
-rw-r--r--Documentation/filesystems/configfs/configfs_example_explicit.c483
-rw-r--r--Documentation/filesystems/configfs/configfs_example_macros.c446
5 files changed, 11 insertions, 961 deletions
diff --git a/Documentation/filesystems/Makefile b/Documentation/filesystems/Makefile
index 13483d192ebb..883010ce5e35 100644
--- a/Documentation/filesystems/Makefile
+++ b/Documentation/filesystems/Makefile
@@ -1,5 +1,3 @@
1subdir-y := configfs
2
3# List of programs to build 1# List of programs to build
4hostprogs-y := dnotify_test 2hostprogs-y := dnotify_test
5 3
diff --git a/Documentation/filesystems/configfs/Makefile b/Documentation/filesystems/configfs/Makefile
deleted file mode 100644
index be7ec5e67dbc..000000000000
--- a/Documentation/filesystems/configfs/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
1ifneq ($(CONFIG_CONFIGFS_FS),)
2obj-m += configfs_example_explicit.o configfs_example_macros.o
3endif
diff --git a/Documentation/filesystems/configfs/configfs.txt b/Documentation/filesystems/configfs/configfs.txt
index b40fec9d3f53..af68efdbbfad 100644
--- a/Documentation/filesystems/configfs/configfs.txt
+++ b/Documentation/filesystems/configfs/configfs.txt
@@ -160,12 +160,6 @@ among other things. For that, it needs a type.
160 160
161 struct configfs_item_operations { 161 struct configfs_item_operations {
162 void (*release)(struct config_item *); 162 void (*release)(struct config_item *);
163 ssize_t (*show_attribute)(struct config_item *,
164 struct configfs_attribute *,
165 char *);
166 ssize_t (*store_attribute)(struct config_item *,
167 struct configfs_attribute *,
168 const char *, size_t);
169 int (*allow_link)(struct config_item *src, 163 int (*allow_link)(struct config_item *src,
170 struct config_item *target); 164 struct config_item *target);
171 int (*drop_link)(struct config_item *src, 165 int (*drop_link)(struct config_item *src,
@@ -183,9 +177,7 @@ The most basic function of a config_item_type is to define what
183operations can be performed on a config_item. All items that have been 177operations can be performed on a config_item. All items that have been
184allocated dynamically will need to provide the ct_item_ops->release() 178allocated dynamically will need to provide the ct_item_ops->release()
185method. This method is called when the config_item's reference count 179method. This method is called when the config_item's reference count
186reaches zero. Items that wish to display an attribute need to provide 180reaches zero.
187the ct_item_ops->show_attribute() method. Similarly, storing a new
188attribute value uses the store_attribute() method.
189 181
190[struct configfs_attribute] 182[struct configfs_attribute]
191 183
@@ -193,6 +185,8 @@ attribute value uses the store_attribute() method.
193 char *ca_name; 185 char *ca_name;
194 struct module *ca_owner; 186 struct module *ca_owner;
195 umode_t ca_mode; 187 umode_t ca_mode;
188 ssize_t (*show)(struct config_item *, char *);
189 ssize_t (*store)(struct config_item *, const char *, size_t);
196 }; 190 };
197 191
198When a config_item wants an attribute to appear as a file in the item's 192When a config_item wants an attribute to appear as a file in the item's
@@ -202,10 +196,10 @@ config_item_type->ct_attrs. When the item appears in configfs, the
202attribute file will appear with the configfs_attribute->ca_name 196attribute file will appear with the configfs_attribute->ca_name
203filename. configfs_attribute->ca_mode specifies the file permissions. 197filename. configfs_attribute->ca_mode specifies the file permissions.
204 198
205If an attribute is readable and the config_item provides a 199If an attribute is readable and provides a ->show method, that method will
206ct_item_ops->show_attribute() method, that method will be called 200be called whenever userspace asks for a read(2) on the attribute. If an
207whenever userspace asks for a read(2) on the attribute. The converse 201attribute is writable and provides a ->store method, that method will be
208will happen for write(2). 202be called whenever userspace asks for a write(2) on the attribute.
209 203
210[struct config_group] 204[struct config_group]
211 205
@@ -311,20 +305,10 @@ the subsystem must be ready for it.
311[An Example] 305[An Example]
312 306
313The best example of these basic concepts is the simple_children 307The best example of these basic concepts is the simple_children
314subsystem/group and the simple_child item in configfs_example_explicit.c 308subsystem/group and the simple_child item in
315and configfs_example_macros.c. It shows a trivial object displaying and 309samples/configfs/configfs_sample.c. It shows a trivial object displaying
316storing an attribute, and a simple group creating and destroying these 310and storing an attribute, and a simple group creating and destroying
317children. 311these children.
318
319The only difference between configfs_example_explicit.c and
320configfs_example_macros.c is how the attributes of the childless item
321are defined. The childless item has extended attributes, each with
322their own show()/store() operation. This follows a convention commonly
323used in sysfs. configfs_example_explicit.c creates these attributes
324by explicitly defining the structures involved. Conversely
325configfs_example_macros.c uses some convenience macros from configfs.h
326to define the attributes. These macros are similar to their sysfs
327counterparts.
328 312
329[Hierarchy Navigation and the Subsystem Mutex] 313[Hierarchy Navigation and the Subsystem Mutex]
330 314
diff --git a/Documentation/filesystems/configfs/configfs_example_explicit.c b/Documentation/filesystems/configfs/configfs_example_explicit.c
deleted file mode 100644
index 1420233dfa55..000000000000
--- a/Documentation/filesystems/configfs/configfs_example_explicit.c
+++ /dev/null
@@ -1,483 +0,0 @@
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
50struct childless {
51 struct configfs_subsystem subsys;
52 int showme;
53 int storeme;
54};
55
56struct 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
62static 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
67static 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
78static ssize_t childless_storeme_read(struct childless *childless,
79 char *page)
80{
81 return sprintf(page, "%d\n", childless->storeme);
82}
83
84static 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
103static 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
115static 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};
119static 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};
124static 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
129static struct configfs_attribute *childless_attrs[] = {
130 &childless_attr_showme.attr,
131 &childless_attr_storeme.attr,
132 &childless_attr_description.attr,
133 NULL,
134};
135
136static 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
150static 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
164static struct configfs_item_operations childless_item_ops = {
165 .show_attribute = childless_attr_show,
166 .store_attribute = childless_attr_store,
167};
168
169static 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
175static 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
198struct simple_child {
199 struct config_item item;
200 int storeme;
201};
202
203static 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
208static 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
214static struct configfs_attribute *simple_child_attrs[] = {
215 &simple_child_attr_storeme,
216 NULL,
217};
218
219static 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
231static 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
251static void simple_child_release(struct config_item *item)
252{
253 kfree(to_simple_child(item));
254}
255
256static 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
262static 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
269struct simple_children {
270 struct config_group group;
271};
272
273static 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
278static 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
294static struct configfs_attribute simple_children_attr_description = {
295 .ca_owner = THIS_MODULE,
296 .ca_name = "description",
297 .ca_mode = S_IRUGO,
298};
299
300static struct configfs_attribute *simple_children_attrs[] = {
301 &simple_children_attr_description,
302 NULL,
303};
304
305static 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
316static void simple_children_release(struct config_item *item)
317{
318 kfree(to_simple_children(item));
319}
320
321static 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 */
330static struct configfs_group_operations simple_children_group_ops = {
331 .make_item = simple_children_make_item,
332};
333
334static 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
341static 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
363static 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
378static struct configfs_attribute group_children_attr_description = {
379 .ca_owner = THIS_MODULE,
380 .ca_name = "description",
381 .ca_mode = S_IRUGO,
382};
383
384static struct configfs_attribute *group_children_attrs[] = {
385 &group_children_attr_description,
386 NULL,
387};
388
389static 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
400static 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 */
408static struct configfs_group_operations group_children_group_ops = {
409 .make_group = group_children_make_group,
410};
411
412static 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
419static 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 */
437static struct configfs_subsystem *example_subsys[] = {
438 &childless_subsys.subsys,
439 &simple_children_subsys,
440 &group_children_subsys,
441 NULL,
442};
443
444static 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
466out_unregister:
467 for (i--; i >= 0; i--)
468 configfs_unregister_subsystem(example_subsys[i]);
469
470 return ret;
471}
472
473static 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
481module_init(configfs_example_init);
482module_exit(configfs_example_exit);
483MODULE_LICENSE("GPL");
diff --git a/Documentation/filesystems/configfs/configfs_example_macros.c b/Documentation/filesystems/configfs/configfs_example_macros.c
deleted file mode 100644
index 327dfbc640a9..000000000000
--- a/Documentation/filesystems/configfs/configfs_example_macros.c
+++ /dev/null
@@ -1,446 +0,0 @@
1/*
2 * vim: noexpandtab ts=8 sts=0 sw=8:
3 *
4 * configfs_example_macros.c - This file is a demonstration module
5 * containing a number of configfs subsystems. It uses the helper
6 * macros defined by configfs.h
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 021110-1307, USA.
22 *
23 * Based on sysfs:
24 * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
25 *
26 * configfs Copyright (C) 2005 Oracle. All rights reserved.
27 */
28
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/slab.h>
32
33#include <linux/configfs.h>
34
35
36
37/*
38 * 01-childless
39 *
40 * This first example is a childless subsystem. It cannot create
41 * any config_items. It just has attributes.
42 *
43 * Note that we are enclosing the configfs_subsystem inside a container.
44 * This is not necessary if a subsystem has no attributes directly
45 * on the subsystem. See the next example, 02-simple-children, for
46 * such a subsystem.
47 */
48
49struct childless {
50 struct configfs_subsystem subsys;
51 int showme;
52 int storeme;
53};
54
55static inline struct childless *to_childless(struct config_item *item)
56{
57 return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
58}
59
60CONFIGFS_ATTR_STRUCT(childless);
61#define CHILDLESS_ATTR(_name, _mode, _show, _store) \
62struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR(_name, _mode, _show, _store)
63#define CHILDLESS_ATTR_RO(_name, _show) \
64struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR_RO(_name, _show);
65
66static ssize_t childless_showme_read(struct childless *childless,
67 char *page)
68{
69 ssize_t pos;
70
71 pos = sprintf(page, "%d\n", childless->showme);
72 childless->showme++;
73
74 return pos;
75}
76
77static ssize_t childless_storeme_read(struct childless *childless,
78 char *page)
79{
80 return sprintf(page, "%d\n", childless->storeme);
81}
82
83static ssize_t childless_storeme_write(struct childless *childless,
84 const char *page,
85 size_t count)
86{
87 unsigned long tmp;
88 char *p = (char *) page;
89
90 tmp = simple_strtoul(p, &p, 10);
91 if (!p || (*p && (*p != '\n')))
92 return -EINVAL;
93
94 if (tmp > INT_MAX)
95 return -ERANGE;
96
97 childless->storeme = tmp;
98
99 return count;
100}
101
102static ssize_t childless_description_read(struct childless *childless,
103 char *page)
104{
105 return sprintf(page,
106"[01-childless]\n"
107"\n"
108"The childless subsystem is the simplest possible subsystem in\n"
109"configfs. It does not support the creation of child config_items.\n"
110"It only has a few attributes. In fact, it isn't much different\n"
111"than a directory in /proc.\n");
112}
113
114CHILDLESS_ATTR_RO(showme, childless_showme_read);
115CHILDLESS_ATTR(storeme, S_IRUGO | S_IWUSR, childless_storeme_read,
116 childless_storeme_write);
117CHILDLESS_ATTR_RO(description, childless_description_read);
118
119static struct configfs_attribute *childless_attrs[] = {
120 &childless_attr_showme.attr,
121 &childless_attr_storeme.attr,
122 &childless_attr_description.attr,
123 NULL,
124};
125
126CONFIGFS_ATTR_OPS(childless);
127static struct configfs_item_operations childless_item_ops = {
128 .show_attribute = childless_attr_show,
129 .store_attribute = childless_attr_store,
130};
131
132static struct config_item_type childless_type = {
133 .ct_item_ops = &childless_item_ops,
134 .ct_attrs = childless_attrs,
135 .ct_owner = THIS_MODULE,
136};
137
138static struct childless childless_subsys = {
139 .subsys = {
140 .su_group = {
141 .cg_item = {
142 .ci_namebuf = "01-childless",
143 .ci_type = &childless_type,
144 },
145 },
146 },
147};
148
149
150/* ----------------------------------------------------------------- */
151
152/*
153 * 02-simple-children
154 *
155 * This example merely has a simple one-attribute child. Note that
156 * there is no extra attribute structure, as the child's attribute is
157 * known from the get-go. Also, there is no container for the
158 * subsystem, as it has no attributes of its own.
159 */
160
161struct simple_child {
162 struct config_item item;
163 int storeme;
164};
165
166static inline struct simple_child *to_simple_child(struct config_item *item)
167{
168 return item ? container_of(item, struct simple_child, item) : NULL;
169}
170
171static struct configfs_attribute simple_child_attr_storeme = {
172 .ca_owner = THIS_MODULE,
173 .ca_name = "storeme",
174 .ca_mode = S_IRUGO | S_IWUSR,
175};
176
177static struct configfs_attribute *simple_child_attrs[] = {
178 &simple_child_attr_storeme,
179 NULL,
180};
181
182static ssize_t simple_child_attr_show(struct config_item *item,
183 struct configfs_attribute *attr,
184 char *page)
185{
186 ssize_t count;
187 struct simple_child *simple_child = to_simple_child(item);
188
189 count = sprintf(page, "%d\n", simple_child->storeme);
190
191 return count;
192}
193
194static ssize_t simple_child_attr_store(struct config_item *item,
195 struct configfs_attribute *attr,
196 const char *page, size_t count)
197{
198 struct simple_child *simple_child = to_simple_child(item);
199 unsigned long tmp;
200 char *p = (char *) page;
201
202 tmp = simple_strtoul(p, &p, 10);
203 if (!p || (*p && (*p != '\n')))
204 return -EINVAL;
205
206 if (tmp > INT_MAX)
207 return -ERANGE;
208
209 simple_child->storeme = tmp;
210
211 return count;
212}
213
214static void simple_child_release(struct config_item *item)
215{
216 kfree(to_simple_child(item));
217}
218
219static struct configfs_item_operations simple_child_item_ops = {
220 .release = simple_child_release,
221 .show_attribute = simple_child_attr_show,
222 .store_attribute = simple_child_attr_store,
223};
224
225static struct config_item_type simple_child_type = {
226 .ct_item_ops = &simple_child_item_ops,
227 .ct_attrs = simple_child_attrs,
228 .ct_owner = THIS_MODULE,
229};
230
231
232struct simple_children {
233 struct config_group group;
234};
235
236static inline struct simple_children *to_simple_children(struct config_item *item)
237{
238 return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
239}
240
241static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
242{
243 struct simple_child *simple_child;
244
245 simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
246 if (!simple_child)
247 return ERR_PTR(-ENOMEM);
248
249 config_item_init_type_name(&simple_child->item, name,
250 &simple_child_type);
251
252 simple_child->storeme = 0;
253
254 return &simple_child->item;
255}
256
257static struct configfs_attribute simple_children_attr_description = {
258 .ca_owner = THIS_MODULE,
259 .ca_name = "description",
260 .ca_mode = S_IRUGO,
261};
262
263static struct configfs_attribute *simple_children_attrs[] = {
264 &simple_children_attr_description,
265 NULL,
266};
267
268static ssize_t simple_children_attr_show(struct config_item *item,
269 struct configfs_attribute *attr,
270 char *page)
271{
272 return sprintf(page,
273"[02-simple-children]\n"
274"\n"
275"This subsystem allows the creation of child config_items. These\n"
276"items have only one attribute that is readable and writeable.\n");
277}
278
279static void simple_children_release(struct config_item *item)
280{
281 kfree(to_simple_children(item));
282}
283
284static struct configfs_item_operations simple_children_item_ops = {
285 .release = simple_children_release,
286 .show_attribute = simple_children_attr_show,
287};
288
289/*
290 * Note that, since no extra work is required on ->drop_item(),
291 * no ->drop_item() is provided.
292 */
293static struct configfs_group_operations simple_children_group_ops = {
294 .make_item = simple_children_make_item,
295};
296
297static struct config_item_type simple_children_type = {
298 .ct_item_ops = &simple_children_item_ops,
299 .ct_group_ops = &simple_children_group_ops,
300 .ct_attrs = simple_children_attrs,
301 .ct_owner = THIS_MODULE,
302};
303
304static struct configfs_subsystem simple_children_subsys = {
305 .su_group = {
306 .cg_item = {
307 .ci_namebuf = "02-simple-children",
308 .ci_type = &simple_children_type,
309 },
310 },
311};
312
313
314/* ----------------------------------------------------------------- */
315
316/*
317 * 03-group-children
318 *
319 * This example reuses the simple_children group from above. However,
320 * the simple_children group is not the subsystem itself, it is a
321 * child of the subsystem. Creation of a group in the subsystem creates
322 * a new simple_children group. That group can then have simple_child
323 * children of its own.
324 */
325
326static struct config_group *group_children_make_group(struct config_group *group, const char *name)
327{
328 struct simple_children *simple_children;
329
330 simple_children = kzalloc(sizeof(struct simple_children),
331 GFP_KERNEL);
332 if (!simple_children)
333 return ERR_PTR(-ENOMEM);
334
335 config_group_init_type_name(&simple_children->group, name,
336 &simple_children_type);
337
338 return &simple_children->group;
339}
340
341static struct configfs_attribute group_children_attr_description = {
342 .ca_owner = THIS_MODULE,
343 .ca_name = "description",
344 .ca_mode = S_IRUGO,
345};
346
347static struct configfs_attribute *group_children_attrs[] = {
348 &group_children_attr_description,
349 NULL,
350};
351
352static ssize_t group_children_attr_show(struct config_item *item,
353 struct configfs_attribute *attr,
354 char *page)
355{
356 return sprintf(page,
357"[03-group-children]\n"
358"\n"
359"This subsystem allows the creation of child config_groups. These\n"
360"groups are like the subsystem simple-children.\n");
361}
362
363static struct configfs_item_operations group_children_item_ops = {
364 .show_attribute = group_children_attr_show,
365};
366
367/*
368 * Note that, since no extra work is required on ->drop_item(),
369 * no ->drop_item() is provided.
370 */
371static struct configfs_group_operations group_children_group_ops = {
372 .make_group = group_children_make_group,
373};
374
375static struct config_item_type group_children_type = {
376 .ct_item_ops = &group_children_item_ops,
377 .ct_group_ops = &group_children_group_ops,
378 .ct_attrs = group_children_attrs,
379 .ct_owner = THIS_MODULE,
380};
381
382static struct configfs_subsystem group_children_subsys = {
383 .su_group = {
384 .cg_item = {
385 .ci_namebuf = "03-group-children",
386 .ci_type = &group_children_type,
387 },
388 },
389};
390
391/* ----------------------------------------------------------------- */
392
393/*
394 * We're now done with our subsystem definitions.
395 * For convenience in this module, here's a list of them all. It
396 * allows the init function to easily register them. Most modules
397 * will only have one subsystem, and will only call register_subsystem
398 * on it directly.
399 */
400static struct configfs_subsystem *example_subsys[] = {
401 &childless_subsys.subsys,
402 &simple_children_subsys,
403 &group_children_subsys,
404 NULL,
405};
406
407static int __init configfs_example_init(void)
408{
409 int ret;
410 int i;
411 struct configfs_subsystem *subsys;
412
413 for (i = 0; example_subsys[i]; i++) {
414 subsys = example_subsys[i];
415
416 config_group_init(&subsys->su_group);
417 mutex_init(&subsys->su_mutex);
418 ret = configfs_register_subsystem(subsys);
419 if (ret) {
420 printk(KERN_ERR "Error %d while registering subsystem %s\n",
421 ret,
422 subsys->su_group.cg_item.ci_namebuf);
423 goto out_unregister;
424 }
425 }
426
427 return 0;
428
429out_unregister:
430 for (i--; i >= 0; i--)
431 configfs_unregister_subsystem(example_subsys[i]);
432
433 return ret;
434}
435
436static void __exit configfs_example_exit(void)
437{
438 int i;
439
440 for (i = 0; example_subsys[i]; i++)
441 configfs_unregister_subsystem(example_subsys[i]);
442}
443
444module_init(configfs_example_init);
445module_exit(configfs_example_exit);
446MODULE_LICENSE("GPL");