Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
48ae744
Documentation
ABI
DocBook
PCI
RCU
accounting
acpi
aoe
arm
auxdisplay
blackfin
block
cdrom
connector
console
controllers
cpu-freq
cpuidle
cris
crypto
device-mapper
driver-model
dvb
early-userspace
fault-injection
fb
filesystems
configfs
configfs.txt
configfs_example.c
00-INDEX
9p.txt
Exporting
Locking
adfs.txt
affs.txt
afs.txt
automount-support.txt
befs.txt
bfs.txt
cifs.txt
coda.txt
cramfs.txt
dentry-locking.txt
directory-locking
dlmfs.txt
dnotify.txt
ecryptfs.txt
ext2.txt
ext3.txt
ext4.txt
files.txt
fuse.txt
gfs2-glocks.txt
gfs2.txt
hfs.txt
hfsplus.txt
hpfs.txt
inotify.txt
isofs.txt
jfs.txt
locks.txt
mandatory-locking.txt
ncpfs.txt
nfs-rdma.txt
nfsroot.txt
ntfs.txt
ocfs2.txt
porting
proc.txt
quota.txt
ramfs-rootfs-initramfs.txt
relay.txt
romfs.txt
rpc-cache.txt
seq_file.txt
sharedsubtree.txt
smbfs.txt
spufs.txt
sysfs-pci.txt
sysfs.txt
sysv-fs.txt
tmpfs.txt
ubifs.txt
udf.txt
ufs.txt
vfat.txt
vfs.txt
xfs.txt
xip.txt
firmware_class
frv
hwmon
i2c
i2o
ia64
ide
infiniband
input
ioctl
isdn
ja_JP
kbuild
kdump
ko_KR
laptops
lguest
m68k
make
mips
mn10300
namespaces
netlabel
networking
parisc
pcmcia
power
powerpc
prctl
s390
scheduler
scsi
serial
sh
sound
sparc
spi
sysctl
telephony
thermal
timers
tracers
uml
usb
video4linux
vm
w1
watchdog
x86
zh_CN
00-INDEX
BUG-HUNTING
Changes
CodingStyle
DMA-API.txt
DMA-ISA-LPC.txt
DMA-attributes.txt
DMA-mapping.txt
HOWTO
IO-mapping.txt
IPMI.txt
IRQ-affinity.txt
IRQ.txt
Intel-IOMMU.txt
MSI-HOWTO.txt
ManagementStyle
README.DAC960
README.cycladesZ
SAK.txt
SM501.txt
SecurityBugs
Smack.txt
SubmitChecklist
SubmittingDrivers
SubmittingPatches
VGA-softcursor.txt
applying-patches.txt
atomic_ops.txt
basic_profiling.txt
binfmt_misc.txt
braille-console.txt
cachetlb.txt
cciss.txt
cgroups.txt
cli-sti-removal.txt
computone.txt
cpqarray.txt
cpu-hotplug.txt
cpu-load.txt
cpusets.txt
cputopology.txt
dcdbas.txt
debugging-modules.txt
debugging-via-ohci1394.txt
dell_rbu.txt
devices.txt
digiepca.txt
dontdiff
edac.txt
eisa.txt
email-clients.txt
exception.txt
feature-removal-schedule.txt
floppy.txt
ftrace.txt
gpio.txt
hayes-esp.txt
highuid.txt
hpet.txt
hw_random.txt
initrd.txt
io_ordering.txt
ioctl-number.txt
iostats.txt
irqflags-tracing.txt
isapnp.txt
java.txt
kernel-doc-nano-HOWTO.txt
kernel-docs.txt
kernel-parameters.txt
keys-request-key.txt
keys.txt
kobject.txt
kprobes.txt
kref.txt
ldm.txt
leds-class.txt
local_ops.txt
lockdep-design.txt
lockstat.txt
logo.gif
logo.txt
magic-number.txt
markers.txt
mca.txt
md.txt
memory-barriers.txt
memory-hotplug.txt
memory.txt
mono.txt
moxa-smartio
mtrr.txt
mutex-design.txt
nbd.txt
nmi_watchdog.txt
nommu-mmap.txt
numastat.txt
oops-tracing.txt
paride.txt
parport-lowlevel.txt
parport.txt
pi-futex.txt
pnp.txt
preempt-locking.txt
prio_tree.txt
ramdisk.txt
rbtree.txt
rfkill.txt
riscom8.txt
robust-futex-ABI.txt
robust-futexes.txt
rocket.txt
rt-mutex-design.txt
rt-mutex.txt
rtc.txt
serial-console.txt
sgi-ioc4.txt
sgi-visws.txt
sparse.txt
specialix.txt
spinlocks.txt
stable_api_nonsense.txt
stable_kernel_rules.txt
stallion.txt
svga.txt
sx.txt
sysfs-rules.txt
sysrq.txt
tty.txt
unaligned-memory-access.txt
unicode.txt
unshare.txt
video-output.txt
volatile-considered-harmful.txt
voyager.txt
zorro.txt
arch
block
crypto
drivers
firmware
fs
include
init
ipc
kernel
lib
mm
net
samples
scripts
security
sound
usr
virt
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
MAINTAINERS
Makefile
README
REPORTING-BUGS
Breadcrumbs
linux
/
Documentation
/
filesystems
/
configfs
/
configfs_example.c
Blame
Blame
Latest commit
History
History
487 lines (399 loc) · 12.3 KB
Breadcrumbs
linux
/
Documentation
/
filesystems
/
configfs
/
configfs_example.c
Top
File metadata and controls
Code
Blame
487 lines (399 loc) · 12.3 KB
Raw
/* * vim: noexpandtab ts=8 sts=0 sw=8: * * configfs_example.c - This file is a demonstration module containing * a number of configfs subsystems. * * 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; }; struct childless_attribute { struct configfs_attribute attr; ssize_t (*show)(struct childless *, char *); ssize_t (*store)(struct childless *, const char *, size_t); }; static inline struct childless *to_childless(struct config_item *item) { return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL; } static ssize_t childless_showme_read(struct childless *childless, char *page) { ssize_t pos; pos = sprintf(page, "%d\n", childless->showme); childless->showme++; return pos; } static ssize_t childless_storeme_read(struct childless *childless, char *page) { return sprintf(page, "%d\n", childless->storeme); } static ssize_t childless_storeme_write(struct childless *childless, const char *page, size_t count) { unsigned long tmp; char *p = (char *) page; tmp = simple_strtoul(p, &p, 10); if (!p || (*p && (*p != '\n'))) return -EINVAL; if (tmp > INT_MAX) return -ERANGE; childless->storeme = tmp; return count; } static ssize_t childless_description_read(struct childless *childless, char *page) { return sprintf(page, "[01-childless]\n" "\n" "The childless subsystem is the simplest possible subsystem in\n" "configfs. It does not support the creation of child config_items.\n" "It only has a few attributes. In fact, it isn't much different\n" "than a directory in /proc.\n"); } static struct childless_attribute childless_attr_showme = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO }, .show = childless_showme_read, }; static struct childless_attribute childless_attr_storeme = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR }, .show = childless_storeme_read, .store = childless_storeme_write, }; static struct childless_attribute childless_attr_description = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO }, .show = childless_description_read, }; static struct configfs_attribute *childless_attrs[] = { &childless_attr_showme.attr, &childless_attr_storeme.attr, &childless_attr_description.attr, NULL, }; static ssize_t childless_attr_show(struct config_item *item, struct configfs_attribute *attr, char *page) { struct childless *childless = to_childless(item); struct childless_attribute *childless_attr = container_of(attr, struct childless_attribute, attr); ssize_t ret = 0; if (childless_attr->show) ret = childless_attr->show(childless, page); return ret; } static ssize_t childless_attr_store(struct config_item *item, struct configfs_attribute *attr, const char *page, size_t count) { struct childless *childless = to_childless(item); struct childless_attribute *childless_attr = container_of(attr, struct childless_attribute, attr); ssize_t ret = -EINVAL; if (childless_attr->store) ret = childless_attr->store(childless, page, count); return ret; } static struct configfs_item_operations childless_item_ops = { .show_attribute = childless_attr_show, .store_attribute = childless_attr_store, }; static struct config_item_type childless_type = { .ct_item_ops = &childless_item_ops, .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; } static struct configfs_attribute simple_child_attr_storeme = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR, }; static struct configfs_attribute *simple_child_attrs[] = { &simple_child_attr_storeme, NULL, }; static ssize_t simple_child_attr_show(struct config_item *item, struct configfs_attribute *attr, char *page) { ssize_t count; struct simple_child *simple_child = to_simple_child(item); count = sprintf(page, "%d\n", simple_child->storeme); return count; } static ssize_t simple_child_attr_store(struct config_item *item, struct configfs_attribute *attr, const char *page, size_t count) { 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 != '\n'))) return -EINVAL; if (tmp > INT_MAX) return -ERANGE; simple_child->storeme = tmp; return count; } 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, .show_attribute = simple_child_attr_show, .store_attribute = simple_child_attr_store, }; static struct config_item_type simple_child_type = { .ct_item_ops = &simple_child_item_ops, .ct_attrs = simple_child_attrs, .ct_owner = THIS_MODULE, }; struct simple_children { struct config_group group; }; static inline struct simple_children *to_simple_children(struct config_item *item) { return item ? container_of(to_config_group(item), struct simple_children, group) : NULL; } static int simple_children_make_item(struct config_group *group, const char *name, struct config_item **new_item) { struct simple_child *simple_child; simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL); if (!simple_child) return -ENOMEM; config_item_init_type_name(&simple_child->item, name, &simple_child_type); simple_child->storeme = 0; *new_item = &simple_child->item; return 0; } static struct configfs_attribute simple_children_attr_description = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO, }; static struct configfs_attribute *simple_children_attrs[] = { &simple_children_attr_description, NULL, }; static ssize_t simple_children_attr_show(struct config_item *item, struct configfs_attribute *attr, char *page) { return sprintf(page, "[02-simple-children]\n" "\n" "This subsystem allows the creation of child config_items. These\n" "items have only one attribute that is readable and writeable.\n"); } static void simple_children_release(struct config_item *item) { kfree(to_simple_children(item)); } static struct configfs_item_operations simple_children_item_ops = { .release = simple_children_release, .show_attribute = simple_children_attr_show, }; /* * 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, .ct_owner = THIS_MODULE, }; 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. */ static int group_children_make_group(struct config_group *group, const char *name, struct config_group **new_group) { struct simple_children *simple_children; simple_children = kzalloc(sizeof(struct simple_children), GFP_KERNEL); if (!simple_children) return -ENOMEM; config_group_init_type_name(&simple_children->group, name, &simple_children_type); *new_group = &simple_children->group; return 0; } static struct configfs_attribute group_children_attr_description = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO, }; static struct configfs_attribute *group_children_attrs[] = { &group_children_attr_description, NULL, }; static ssize_t group_children_attr_show(struct config_item *item, struct configfs_attribute *attr, char *page) { return sprintf(page, "[03-group-children]\n" "\n" "This subsystem allows the creation of child config_groups. These\n" "groups are like the subsystem simple-children.\n"); } static struct configfs_item_operations group_children_item_ops = { .show_attribute = group_children_attr_show, }; /* * 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 = { .ct_item_ops = &group_children_item_ops, .ct_group_ops = &group_children_group_ops, .ct_attrs = group_children_attrs, .ct_owner = THIS_MODULE, }; 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); mutex_init(&subsys->su_mutex); ret = configfs_register_subsystem(subsys); if (ret) { printk(KERN_ERR "Error %d while registering subsystem %s\n", ret, subsys->su_group.cg_item.ci_namebuf); goto out_unregister; } } return 0; out_unregister: for (; i >= 0; i--) { configfs_unregister_subsystem(example_subsys[i]); } return ret; } static void __exit configfs_example_exit(void) { int i; for (i = 0; example_subsys[i]; i++) { configfs_unregister_subsystem(example_subsys[i]); } } module_init(configfs_example_init); module_exit(configfs_example_exit); MODULE_LICENSE("GPL");
1
2
3
4
5
6
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
You can’t perform that action at this time.