Blame view

samples/configfs/configfs_sample.c 9.89 KB
7063fbf22   Joel Becker   [PATCH] configfs:...
1
2
3
  /*
   * vim: noexpandtab ts=8 sts=0 sw=8:
   *
ecb3d28c7   Joel Becker   [PATCH] configfs:...
4
5
6
   * configfs_example_macros.c - This file is a demonstration module
   *      containing a number of configfs subsystems.  It uses the helper
   *      macros defined by configfs.h
7063fbf22   Joel Becker   [PATCH] configfs:...
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public
   * License as published by the Free Software Foundation; either
   * version 2 of the License, or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public
   * License along with this program; if not, write to the
   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   * Boston, MA 021110-1307, USA.
   *
   * Based on sysfs:
   * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
   *
   * configfs Copyright (C) 2005 Oracle.  All rights reserved.
   */
  
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/slab.h>
  
  #include <linux/configfs.h>
  
  
  
  /*
   * 01-childless
   *
   * This first example is a childless subsystem.  It cannot create
   * any config_items.  It just has attributes.
   *
   * Note that we are enclosing the configfs_subsystem inside a container.
   * This is not necessary if a subsystem has no attributes directly
   * on the subsystem.  See the next example, 02-simple-children, for
   * such a subsystem.
   */
  
  struct childless {
  	struct configfs_subsystem subsys;
  	int showme;
  	int storeme;
  };
7063fbf22   Joel Becker   [PATCH] configfs:...
54
55
  static inline struct childless *to_childless(struct config_item *item)
  {
517982229   Christoph Hellwig   configfs: remove ...
56
57
  	return item ? container_of(to_configfs_subsystem(to_config_group(item)),
  			struct childless, subsys) : NULL;
7063fbf22   Joel Becker   [PATCH] configfs:...
58
  }
517982229   Christoph Hellwig   configfs: remove ...
59
  static ssize_t childless_showme_show(struct config_item *item, char *page)
7063fbf22   Joel Becker   [PATCH] configfs:...
60
  {
517982229   Christoph Hellwig   configfs: remove ...
61
  	struct childless *childless = to_childless(item);
7063fbf22   Joel Becker   [PATCH] configfs:...
62
63
64
65
66
67
68
69
  	ssize_t pos;
  
  	pos = sprintf(page, "%d
  ", childless->showme);
  	childless->showme++;
  
  	return pos;
  }
517982229   Christoph Hellwig   configfs: remove ...
70
  static ssize_t childless_storeme_show(struct config_item *item, char *page)
7063fbf22   Joel Becker   [PATCH] configfs:...
71
  {
517982229   Christoph Hellwig   configfs: remove ...
72
73
  	return sprintf(page, "%d
  ", to_childless(item)->storeme);
7063fbf22   Joel Becker   [PATCH] configfs:...
74
  }
517982229   Christoph Hellwig   configfs: remove ...
75
76
  static ssize_t childless_storeme_store(struct config_item *item,
  		const char *page, size_t count)
7063fbf22   Joel Becker   [PATCH] configfs:...
77
  {
517982229   Christoph Hellwig   configfs: remove ...
78
  	struct childless *childless = to_childless(item);
7063fbf22   Joel Becker   [PATCH] configfs:...
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
  	unsigned long tmp;
  	char *p = (char *) page;
  
  	tmp = simple_strtoul(p, &p, 10);
  	if (!p || (*p && (*p != '
  ')))
  		return -EINVAL;
  
  	if (tmp > INT_MAX)
  		return -ERANGE;
  
  	childless->storeme = tmp;
  
  	return count;
  }
517982229   Christoph Hellwig   configfs: remove ...
94
  static ssize_t childless_description_show(struct config_item *item, char *page)
7063fbf22   Joel Becker   [PATCH] configfs:...
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  {
  	return sprintf(page,
  "[01-childless]
  "
  "
  "
  "The childless subsystem is the simplest possible subsystem in
  "
  "configfs.  It does not support the creation of child config_items.
  "
  "It only has a few attributes.  In fact, it isn't much different
  "
  "than a directory in /proc.
  ");
  }
517982229   Christoph Hellwig   configfs: remove ...
110
111
112
  CONFIGFS_ATTR_RO(childless_, showme);
  CONFIGFS_ATTR(childless_, storeme);
  CONFIGFS_ATTR_RO(childless_, description);
7063fbf22   Joel Becker   [PATCH] configfs:...
113
114
  
  static struct configfs_attribute *childless_attrs[] = {
517982229   Christoph Hellwig   configfs: remove ...
115
116
117
  	&childless_attr_showme,
  	&childless_attr_storeme,
  	&childless_attr_description,
7063fbf22   Joel Becker   [PATCH] configfs:...
118
119
  	NULL,
  };
7063fbf22   Joel Becker   [PATCH] configfs:...
120
  static struct config_item_type childless_type = {
7063fbf22   Joel Becker   [PATCH] configfs:...
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
  	.ct_attrs	= childless_attrs,
  	.ct_owner	= THIS_MODULE,
  };
  
  static struct childless childless_subsys = {
  	.subsys = {
  		.su_group = {
  			.cg_item = {
  				.ci_namebuf = "01-childless",
  				.ci_type = &childless_type,
  			},
  		},
  	},
  };
  
  
  /* ----------------------------------------------------------------- */
  
  /*
   * 02-simple-children
   *
   * This example merely has a simple one-attribute child.  Note that
   * there is no extra attribute structure, as the child's attribute is
   * known from the get-go.  Also, there is no container for the
   * subsystem, as it has no attributes of its own.
   */
  
  struct simple_child {
  	struct config_item item;
  	int storeme;
  };
  
  static inline struct simple_child *to_simple_child(struct config_item *item)
  {
  	return item ? container_of(item, struct simple_child, item) : NULL;
  }
517982229   Christoph Hellwig   configfs: remove ...
157
  static ssize_t simple_child_storeme_show(struct config_item *item, char *page)
7063fbf22   Joel Becker   [PATCH] configfs:...
158
  {
517982229   Christoph Hellwig   configfs: remove ...
159
160
  	return sprintf(page, "%d
  ", to_simple_child(item)->storeme);
7063fbf22   Joel Becker   [PATCH] configfs:...
161
  }
517982229   Christoph Hellwig   configfs: remove ...
162
163
  static ssize_t simple_child_storeme_store(struct config_item *item,
  		const char *page, size_t count)
7063fbf22   Joel Becker   [PATCH] configfs:...
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
  {
  	struct simple_child *simple_child = to_simple_child(item);
  	unsigned long tmp;
  	char *p = (char *) page;
  
  	tmp = simple_strtoul(p, &p, 10);
  	if (!p || (*p && (*p != '
  ')))
  		return -EINVAL;
  
  	if (tmp > INT_MAX)
  		return -ERANGE;
  
  	simple_child->storeme = tmp;
  
  	return count;
  }
517982229   Christoph Hellwig   configfs: remove ...
181
182
183
184
185
186
  CONFIGFS_ATTR(simple_child_, storeme);
  
  static struct configfs_attribute *simple_child_attrs[] = {
  	&simple_child_attr_storeme,
  	NULL,
  };
7063fbf22   Joel Becker   [PATCH] configfs:...
187
188
189
190
191
192
193
  static void simple_child_release(struct config_item *item)
  {
  	kfree(to_simple_child(item));
  }
  
  static struct configfs_item_operations simple_child_item_ops = {
  	.release		= simple_child_release,
7063fbf22   Joel Becker   [PATCH] configfs:...
194
195
196
197
198
199
200
  };
  
  static struct config_item_type simple_child_type = {
  	.ct_item_ops	= &simple_child_item_ops,
  	.ct_attrs	= simple_child_attrs,
  	.ct_owner	= THIS_MODULE,
  };
22dd0e88b   Joel Becker   configfs: Release...
201
202
203
204
205
206
  struct simple_children {
  	struct config_group group;
  };
  
  static inline struct simple_children *to_simple_children(struct config_item *item)
  {
517982229   Christoph Hellwig   configfs: remove ...
207
208
  	return item ? container_of(to_config_group(item),
  			struct simple_children, group) : NULL;
22dd0e88b   Joel Becker   configfs: Release...
209
  }
517982229   Christoph Hellwig   configfs: remove ...
210
211
  static struct config_item *simple_children_make_item(struct config_group *group,
  		const char *name)
7063fbf22   Joel Becker   [PATCH] configfs:...
212
213
  {
  	struct simple_child *simple_child;
dd00cc486   Yoann Padioleau   some kmalloc/mems...
214
  	simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
7063fbf22   Joel Becker   [PATCH] configfs:...
215
  	if (!simple_child)
a6795e9eb   Joel Becker   configfs: Allow -...
216
  		return ERR_PTR(-ENOMEM);
7063fbf22   Joel Becker   [PATCH] configfs:...
217

7063fbf22   Joel Becker   [PATCH] configfs:...
218
219
220
221
  	config_item_init_type_name(&simple_child->item, name,
  				   &simple_child_type);
  
  	simple_child->storeme = 0;
f89ab8619   Joel Becker   Revert "configfs:...
222
  	return &simple_child->item;
7063fbf22   Joel Becker   [PATCH] configfs:...
223
  }
517982229   Christoph Hellwig   configfs: remove ...
224
225
  static ssize_t simple_children_description_show(struct config_item *item,
  		char *page)
7063fbf22   Joel Becker   [PATCH] configfs:...
226
227
228
229
230
231
232
233
234
235
236
  {
  	return sprintf(page,
  "[02-simple-children]
  "
  "
  "
  "This subsystem allows the creation of child config_items.  These
  "
  "items have only one attribute that is readable and writeable.
  ");
  }
517982229   Christoph Hellwig   configfs: remove ...
237
238
239
240
241
242
  CONFIGFS_ATTR_RO(simple_children_, description);
  
  static struct configfs_attribute *simple_children_attrs[] = {
  	&simple_children_attr_description,
  	NULL,
  };
22dd0e88b   Joel Becker   configfs: Release...
243
244
245
246
  static void simple_children_release(struct config_item *item)
  {
  	kfree(to_simple_children(item));
  }
7063fbf22   Joel Becker   [PATCH] configfs:...
247
  static struct configfs_item_operations simple_children_item_ops = {
ecb3d28c7   Joel Becker   [PATCH] configfs:...
248
  	.release	= simple_children_release,
7063fbf22   Joel Becker   [PATCH] configfs:...
249
250
251
252
253
254
255
256
257
258
259
260
261
262
  };
  
  /*
   * Note that, since no extra work is required on ->drop_item(),
   * no ->drop_item() is provided.
   */
  static struct configfs_group_operations simple_children_group_ops = {
  	.make_item	= simple_children_make_item,
  };
  
  static struct config_item_type simple_children_type = {
  	.ct_item_ops	= &simple_children_item_ops,
  	.ct_group_ops	= &simple_children_group_ops,
  	.ct_attrs	= simple_children_attrs,
3d0f89bb1   Joel Becker   configfs: Add per...
263
  	.ct_owner	= THIS_MODULE,
7063fbf22   Joel Becker   [PATCH] configfs:...
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  };
  
  static struct configfs_subsystem simple_children_subsys = {
  	.su_group = {
  		.cg_item = {
  			.ci_namebuf = "02-simple-children",
  			.ci_type = &simple_children_type,
  		},
  	},
  };
  
  
  /* ----------------------------------------------------------------- */
  
  /*
   * 03-group-children
   *
   * This example reuses the simple_children group from above.  However,
   * the simple_children group is not the subsystem itself, it is a
   * child of the subsystem.  Creation of a group in the subsystem creates
   * a new simple_children group.  That group can then have simple_child
   * children of its own.
   */
517982229   Christoph Hellwig   configfs: remove ...
287
288
  static struct config_group *group_children_make_group(
  		struct config_group *group, const char *name)
7063fbf22   Joel Becker   [PATCH] configfs:...
289
290
  {
  	struct simple_children *simple_children;
dd00cc486   Yoann Padioleau   some kmalloc/mems...
291
  	simple_children = kzalloc(sizeof(struct simple_children),
7063fbf22   Joel Becker   [PATCH] configfs:...
292
293
  				  GFP_KERNEL);
  	if (!simple_children)
a6795e9eb   Joel Becker   configfs: Allow -...
294
  		return ERR_PTR(-ENOMEM);
7063fbf22   Joel Becker   [PATCH] configfs:...
295

7063fbf22   Joel Becker   [PATCH] configfs:...
296
297
  	config_group_init_type_name(&simple_children->group, name,
  				    &simple_children_type);
f89ab8619   Joel Becker   Revert "configfs:...
298
  	return &simple_children->group;
7063fbf22   Joel Becker   [PATCH] configfs:...
299
  }
517982229   Christoph Hellwig   configfs: remove ...
300
301
  static ssize_t group_children_description_show(struct config_item *item,
  		char *page)
7063fbf22   Joel Becker   [PATCH] configfs:...
302
303
304
305
306
307
308
309
310
311
312
  {
  	return sprintf(page,
  "[03-group-children]
  "
  "
  "
  "This subsystem allows the creation of child config_groups.  These
  "
  "groups are like the subsystem simple-children.
  ");
  }
517982229   Christoph Hellwig   configfs: remove ...
313
314
315
316
317
  CONFIGFS_ATTR_RO(group_children_, description);
  
  static struct configfs_attribute *group_children_attrs[] = {
  	&group_children_attr_description,
  	NULL,
7063fbf22   Joel Becker   [PATCH] configfs:...
318
319
320
321
322
323
324
325
326
327
328
  };
  
  /*
   * Note that, since no extra work is required on ->drop_item(),
   * no ->drop_item() is provided.
   */
  static struct configfs_group_operations group_children_group_ops = {
  	.make_group	= group_children_make_group,
  };
  
  static struct config_item_type group_children_type = {
7063fbf22   Joel Becker   [PATCH] configfs:...
329
330
  	.ct_group_ops	= &group_children_group_ops,
  	.ct_attrs	= group_children_attrs,
3d0f89bb1   Joel Becker   configfs: Add per...
331
  	.ct_owner	= THIS_MODULE,
7063fbf22   Joel Becker   [PATCH] configfs:...
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
  };
  
  static struct configfs_subsystem group_children_subsys = {
  	.su_group = {
  		.cg_item = {
  			.ci_namebuf = "03-group-children",
  			.ci_type = &group_children_type,
  		},
  	},
  };
  
  /* ----------------------------------------------------------------- */
  
  /*
   * We're now done with our subsystem definitions.
   * For convenience in this module, here's a list of them all.  It
   * allows the init function to easily register them.  Most modules
   * will only have one subsystem, and will only call register_subsystem
   * on it directly.
   */
  static struct configfs_subsystem *example_subsys[] = {
  	&childless_subsys.subsys,
  	&simple_children_subsys,
  	&group_children_subsys,
  	NULL,
  };
  
  static int __init configfs_example_init(void)
  {
  	int ret;
  	int i;
  	struct configfs_subsystem *subsys;
  
  	for (i = 0; example_subsys[i]; i++) {
  		subsys = example_subsys[i];
  
  		config_group_init(&subsys->su_group);
e6bd07aee   Joel Becker   configfs: Convert...
369
  		mutex_init(&subsys->su_mutex);
7063fbf22   Joel Becker   [PATCH] configfs:...
370
371
372
373
374
375
376
377
378
379
380
381
382
  		ret = configfs_register_subsystem(subsys);
  		if (ret) {
  			printk(KERN_ERR "Error %d while registering subsystem %s
  ",
  			       ret,
  			       subsys->su_group.cg_item.ci_namebuf);
  			goto out_unregister;
  		}
  	}
  
  	return 0;
  
  out_unregister:
dcb3a08e6   Jiri Slaby   Documentation: co...
383
  	for (i--; i >= 0; i--)
7063fbf22   Joel Becker   [PATCH] configfs:...
384
  		configfs_unregister_subsystem(example_subsys[i]);
7063fbf22   Joel Becker   [PATCH] configfs:...
385
386
387
388
389
390
391
  
  	return ret;
  }
  
  static void __exit configfs_example_exit(void)
  {
  	int i;
dcb3a08e6   Jiri Slaby   Documentation: co...
392
  	for (i = 0; example_subsys[i]; i++)
7063fbf22   Joel Becker   [PATCH] configfs:...
393
  		configfs_unregister_subsystem(example_subsys[i]);
7063fbf22   Joel Becker   [PATCH] configfs:...
394
395
396
397
398
  }
  
  module_init(configfs_example_init);
  module_exit(configfs_example_exit);
  MODULE_LICENSE("GPL");