📄 bobtest.c
字号:
return sprintf(page, "%d\n", jerry->storeme);}static ssize_t jerry_storeme_write(struct jerry *jerry, 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; jerry->storeme = tmp; return count;}static struct jerry_attribute jerry_attr_showme = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO }, .show = jerry_showme_read,};static struct jerry_attribute jerry_attr_storeme = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR }, .show = jerry_storeme_read, .store = jerry_storeme_write,};static struct configfs_attribute *jerry_attrs[] = { &jerry_attr_showme.attr, &jerry_attr_storeme.attr, NULL,};static ssize_t jerry_attr_show(struct config_item *item, struct configfs_attribute *attr, char *page){ struct jerry *jerry = to_jerry(item); struct jerry_attribute *jerry_attr = container_of(attr, struct jerry_attribute, attr); ssize_t ret = 0; if (jerry_attr->show) ret = jerry_attr->show(jerry, page); return ret;}static ssize_t jerry_attr_store(struct config_item *item, struct configfs_attribute *attr, const char *page, size_t count){ struct jerry *jerry = to_jerry(item); struct jerry_attribute *jerry_attr = container_of(attr, struct jerry_attribute, attr); ssize_t ret = -EINVAL; if (jerry_attr->store) ret = jerry_attr->store(jerry, page, count); return ret;}static void jerry_release(struct config_item *item){ printk("Show me the money!\n"); kfree(to_jerry(item));}static int jerry_allow_link(struct config_item *src, struct config_item *target){ int ret = 0; if (target->ci_type != &bob_type) ret = -EINVAL; return ret;}static struct configfs_item_operations jerry_item_ops = { .release = jerry_release, .show_attribute = jerry_attr_show, .store_attribute = jerry_attr_store, .allow_link = jerry_allow_link,};static struct config_item_type jerry_type = { .ct_item_ops = &jerry_item_ops, .ct_attrs = jerry_attrs, .ct_owner = THIS_MODULE,};struct tom { struct config_group group; int showme; int storeme;};struct tom_attribute { struct configfs_attribute attr; ssize_t (*show)(struct tom *, char *); ssize_t (*store)(struct tom *, const char *, size_t);};static inline struct tom *to_tom(struct config_item *item){ return item ? container_of(to_config_group(item), struct tom, group) : NULL;}static ssize_t tom_showme_read(struct tom *tom, char *page){ ssize_t pos; pos = sprintf(page, "%d\n", tom->showme); tom->showme++; return pos;}static ssize_t tom_storeme_read(struct tom *tom, char *page){ return sprintf(page, "%d\n", tom->storeme);}static ssize_t tom_storeme_write(struct tom *tom, 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; tom->storeme = tmp; return count;}static struct tom_attribute tom_attr_showme = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO }, .show = tom_showme_read,};static struct tom_attribute tom_attr_storeme = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR }, .show = tom_storeme_read, .store = tom_storeme_write,};static struct configfs_attribute *tom_attrs[] = { &tom_attr_showme.attr, &tom_attr_storeme.attr, NULL,};static ssize_t tom_attr_show(struct config_item *item, struct configfs_attribute *attr, char *page){ struct tom *tom = to_tom(item); struct tom_attribute *tom_attr = container_of(attr, struct tom_attribute, attr); ssize_t ret = 0; if (tom_attr->show) ret = tom_attr->show(tom, page); return ret;}static ssize_t tom_attr_store(struct config_item *item, struct configfs_attribute *attr, const char *page, size_t count){ struct tom *tom = to_tom(item); struct tom_attribute *tom_attr = container_of(attr, struct tom_attribute, attr); ssize_t ret = -EINVAL; if (tom_attr->store) ret = tom_attr->store(tom, page, count); return ret;}static void tom_release(struct config_item *item){ struct tom *tom = to_tom(item); printk("Oooh, that's gonna leave a mark!\n"); kfree(tom->group.default_groups); kfree(tom);}static struct configfs_item_operations tom_item_ops = { .release = tom_release, .show_attribute = tom_attr_show, .store_attribute = tom_attr_store,};static struct config_item_type tom_type = { .ct_item_ops = &tom_item_ops, .ct_attrs = tom_attrs, .ct_owner = THIS_MODULE,};struct tomset { struct configfs_subsystem subsys; int n_toms;};struct tomset_attribute { struct configfs_attribute attr; ssize_t (*show)(struct tomset *, char *);};static inline struct tomset *to_tomset(struct config_group *group){ return group ? container_of(to_configfs_subsystem(group), struct tomset, subsys) : NULL;}static ssize_t tomset_attr_show(struct config_item *item, struct configfs_attribute *attr, char *page){ struct tomset *tomset = to_tomset(to_config_group(item)); struct tomset_attribute *tomset_attr = container_of(attr, struct tomset_attribute, attr); ssize_t ret = 0; if (tomset_attr->show) ret = tomset_attr->show(tomset, page); return ret;}static ssize_t tomset_toms_read(struct tomset *tomset, char *page){ return sprintf(page, "%d Toms love you\n", tomset->n_toms);}static struct tomset_attribute tomset_attr_toms = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "toms", .ca_mode = S_IRUGO }, .show = tomset_toms_read};static struct configfs_attribute *tomset_attrs[] = { &tomset_attr_toms.attr, NULL,};static struct config_group *make_tom(struct config_group *group, const char *name){ struct tomset *tomset = to_tomset(group); struct tom *tom; struct jerry *jerry; tom = kmalloc(sizeof(struct tom), GFP_KERNEL); if (!tom) return NULL; memset(tom, 0, sizeof(struct tom)); tom->group.default_groups = kmalloc(sizeof(struct config_group *) * 2, GFP_KERNEL); if (!tom->group.default_groups) { kfree(tom); return NULL; } jerry = kmalloc(sizeof(struct jerry), GFP_KERNEL); if (!jerry) { kfree(tom->group.default_groups); kfree(tom); return NULL; } memset(jerry, 0, sizeof(struct jerry)); config_group_init_type_name(&tom->group, name, &tom_type); tom->showme = 0; tom->storeme = 0; tomset->n_toms++; config_group_init_type_name(&jerry->group, "jer", &jerry_type); tom->group.default_groups[0] = &jerry->group; tom->group.default_groups[1] = NULL; return &tom->group;}static void drop_tom(struct config_group *group, struct config_item *item){ struct tomset *tomset = to_tomset(group); struct tom *tom = to_tom(item); config_item_put(&tom->group.default_groups[0]->cg_item); tomset->n_toms--; config_item_put(item);}static struct configfs_item_operations tomset_item_ops = { .show_attribute = tomset_attr_show,};static struct configfs_group_operations tomset_group_ops = { .make_group = make_tom, .drop_item = drop_tom,};static struct config_item_type tomset_type = { .ct_item_ops = &tomset_item_ops, .ct_group_ops = &tomset_group_ops, .ct_attrs = tomset_attrs,};static struct tomset tomset = { .subsys = { .su_group = { .cg_item = { .ci_namebuf = "tomset", .ci_type = &tomset_type, }, }, }, .n_toms = 0,};static int __init bobtest_init(void){ int ret; config_group_init(&bobset.subsys.su_group); init_MUTEX(&bobset.subsys.su_sem); config_group_init(&robert.group); config_group_init(&tomset.subsys.su_group); init_MUTEX(&tomset.subsys.su_sem); ret = configfs_register_subsystem(&bobset.subsys); if (!ret) ret = configfs_register_subsystem(&tomset.subsys); if (ret) printk(KERN_ERR "bobtest: Registration returned %d\n", ret); return ret;}static void __exit bobtest_exit(void){ configfs_unregister_subsystem(&tomset.subsys); configfs_unregister_subsystem(&bobset.subsys);}module_init(bobtest_init);module_exit(bobtest_exit);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -