📄 bobtest.c
字号:
/* * vim: noexpandtab ts=8 sts=0 sw=8: * * 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>/* * Bobs - default_set as part of subsystem. */struct robert { struct config_group group;};struct robert_attribute { struct configfs_attribute attr; ssize_t (*show)(struct robert *, char *);};static inline struct robert *to_robert(struct config_item *item){ return item ? container_of(to_config_group(item), struct robert, group) : NULL;}static ssize_t robert_print_read(struct robert *robert, char *page){ ssize_t pos; pos = sprintf(page, "%s\n", "This is a default bob"); return pos;}static struct robert_attribute robert_attr_print = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "print", .ca_mode = S_IRUGO }, .show = robert_print_read,};static struct configfs_attribute *robert_attrs[] = { &robert_attr_print.attr, NULL,};static ssize_t robert_attr_show(struct config_item *item, struct configfs_attribute *attr, char *page){ struct robert *robert = to_robert(item); struct robert_attribute *robert_attr = container_of(attr, struct robert_attribute, attr); ssize_t ret = 0; if (robert_attr->show) ret = robert_attr->show(robert, page); return ret;}static void robert_release(struct config_item *item){ printk("We shall welease, Wobewt!\n"); kfree(to_robert(item));}static struct configfs_item_operations robert_item_ops = { .release = robert_release, .show_attribute = robert_attr_show,};static struct config_item_type robert_type = { .ct_item_ops = &robert_item_ops, .ct_attrs = robert_attrs, .ct_owner = THIS_MODULE,};static struct robert robert = { .group = { .cg_item = { .ci_namebuf = "robert", .ci_type = &robert_type, }, },};struct bob { struct config_item item; int showme; int storeme;};struct bob_attribute { struct configfs_attribute attr; ssize_t (*show)(struct bob *, char *); ssize_t (*store)(struct bob *, const char *, size_t);};static inline struct bob *to_bob(struct config_item *item){ return item ? container_of(item, struct bob, item) : NULL;}static ssize_t bob_showme_read(struct bob *bob, char *page){ ssize_t pos; pos = sprintf(page, "%d\n", bob->showme); bob->showme++; return pos;}static ssize_t bob_storeme_read(struct bob *bob, char *page){ return sprintf(page, "%d\n", bob->storeme);}static ssize_t bob_storeme_write(struct bob *bob, 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; bob->storeme = tmp; return count;}static struct bob_attribute bob_attr_showme = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO }, .show = bob_showme_read,};static struct bob_attribute bob_attr_storeme = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR }, .show = bob_storeme_read, .store = bob_storeme_write,};static struct configfs_attribute *bob_attrs[] = { &bob_attr_showme.attr, &bob_attr_storeme.attr, NULL,};static ssize_t bob_attr_show(struct config_item *item, struct configfs_attribute *attr, char *page){ struct bob *bob = to_bob(item); struct bob_attribute *bob_attr = container_of(attr, struct bob_attribute, attr); ssize_t ret = 0; if (bob_attr->show) ret = bob_attr->show(bob, page); return ret;}static ssize_t bob_attr_store(struct config_item *item, struct configfs_attribute *attr, const char *page, size_t count){ struct bob *bob = to_bob(item); struct bob_attribute *bob_attr = container_of(attr, struct bob_attribute, attr); ssize_t ret = -EINVAL; if (bob_attr->store) ret = bob_attr->store(bob, page, count); return ret;}static void bob_release(struct config_item *item){ printk("Yeah, uh, we'll talk to Bob\n"); kfree(to_bob(item));}static struct configfs_item_operations bob_item_ops = { .release = bob_release, .show_attribute = bob_attr_show, .store_attribute = bob_attr_store,};static struct config_item_type bob_type = { .ct_item_ops = &bob_item_ops, .ct_attrs = bob_attrs, .ct_owner = THIS_MODULE,};struct bobset { struct configfs_subsystem subsys; int n_bobs;};struct bobset_attribute { struct configfs_attribute attr; ssize_t (*show)(struct bobset *, char *);};static inline struct bobset *to_bobset(struct config_group *group){ return group ? container_of(to_configfs_subsystem(group), struct bobset, subsys) : NULL;}static ssize_t bobset_attr_show(struct config_item *item, struct configfs_attribute *attr, char *page){ struct bobset *bobset = to_bobset(to_config_group(item)); struct bobset_attribute *bobset_attr = container_of(attr, struct bobset_attribute, attr); ssize_t ret = 0; if (bobset_attr->show) ret = bobset_attr->show(bobset, page); return ret;}static ssize_t bobset_bobs_read(struct bobset *bobset, char *page){ return sprintf(page, "%d Bobs love you\n", bobset->n_bobs);}static struct bobset_attribute bobset_attr_bobs = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "bobs", .ca_mode = S_IRUGO }, .show = bobset_bobs_read};static struct configfs_attribute *bobset_attrs[] = { &bobset_attr_bobs.attr, NULL,};static struct config_group *bobset_sets[] = { &robert.group, NULL,};static struct config_item *make_bob(struct config_group *group, const char *name){ struct bobset *bobset = to_bobset(group); struct bob *bob; bob = kmalloc(sizeof(struct bob), GFP_KERNEL); if (!bob) return NULL; memset(bob, 0, sizeof(struct bob)); config_item_init_type_name(&bob->item, name, &bob_type); bob->showme = 0; bob->storeme = 0; bobset->n_bobs++; return &bob->item;}static void drop_bob(struct config_group *group, struct config_item *item){ struct bobset *bobset = to_bobset(group); bobset->n_bobs--; config_item_put(item);}static struct configfs_item_operations bobset_item_ops = { .show_attribute = bobset_attr_show,};static struct configfs_group_operations bobset_group_ops = { .make_item = make_bob, .drop_item = drop_bob,};static struct config_item_type bobset_type = { .ct_item_ops = &bobset_item_ops, .ct_group_ops = &bobset_group_ops, .ct_attrs = bobset_attrs,};static struct bobset bobset = { .subsys = { .su_group = { .cg_item = { .ci_namebuf = "bobset", .ci_type = &bobset_type, }, .default_groups = bobset_sets, }, }, .n_bobs = 0,};/* * Toms - default_set as part of a created set. */struct jerry { struct config_group group; int showme; int storeme;};struct jerry_attribute { struct configfs_attribute attr; ssize_t (*show)(struct jerry *, char *); ssize_t (*store)(struct jerry *, const char *, size_t);};static inline struct jerry *to_jerry(struct config_item *item){ return item ? container_of(to_config_group(item), struct jerry, group) : NULL;}static ssize_t jerry_showme_read(struct jerry *jerry, char *page){ ssize_t pos; pos = sprintf(page, "%d\n", jerry->showme); jerry->showme++; return pos;}static ssize_t jerry_storeme_read(struct jerry *jerry, char *page){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -