linux/samples/configfs/configfs_sample.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * vim: noexpandtab ts=8 sts=0 sw=8:
   4 *
   5 * configfs_example_macros.c - This file is a demonstration module
   6 *      containing a number of configfs subsystems.  It uses the helper
   7 *      macros defined by configfs.h
   8 *
   9 * Based on sysfs:
  10 *      sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
  11 *
  12 * configfs Copyright (C) 2005 Oracle.  All rights reserved.
  13 */
  14
  15#include <linux/init.h>
  16#include <linux/module.h>
  17#include <linux/slab.h>
  18
  19#include <linux/configfs.h>
  20
  21
  22
  23/*
  24 * 01-childless
  25 *
  26 * This first example is a childless subsystem.  It cannot create
  27 * any config_items.  It just has attributes.
  28 *
  29 * Note that we are enclosing the configfs_subsystem inside a container.
  30 * This is not necessary if a subsystem has no attributes directly
  31 * on the subsystem.  See the next example, 02-simple-children, for
  32 * such a subsystem.
  33 */
  34
  35struct childless {
  36        struct configfs_subsystem subsys;
  37        int showme;
  38        int storeme;
  39};
  40
  41static inline struct childless *to_childless(struct config_item *item)
  42{
  43        return item ? container_of(to_configfs_subsystem(to_config_group(item)),
  44                        struct childless, subsys) : NULL;
  45}
  46
  47static ssize_t childless_showme_show(struct config_item *item, char *page)
  48{
  49        struct childless *childless = to_childless(item);
  50        ssize_t pos;
  51
  52        pos = sprintf(page, "%d\n", childless->showme);
  53        childless->showme++;
  54
  55        return pos;
  56}
  57
  58static ssize_t childless_storeme_show(struct config_item *item, char *page)
  59{
  60        return sprintf(page, "%d\n", to_childless(item)->storeme);
  61}
  62
  63static ssize_t childless_storeme_store(struct config_item *item,
  64                const char *page, size_t count)
  65{
  66        struct childless *childless = to_childless(item);
  67        unsigned long tmp;
  68        char *p = (char *) page;
  69
  70        tmp = simple_strtoul(p, &p, 10);
  71        if (!p || (*p && (*p != '\n')))
  72                return -EINVAL;
  73
  74        if (tmp > INT_MAX)
  75                return -ERANGE;
  76
  77        childless->storeme = tmp;
  78
  79        return count;
  80}
  81
  82static ssize_t childless_description_show(struct config_item *item, char *page)
  83{
  84        return sprintf(page,
  85"[01-childless]\n"
  86"\n"
  87"The childless subsystem is the simplest possible subsystem in\n"
  88"configfs.  It does not support the creation of child config_items.\n"
  89"It only has a few attributes.  In fact, it isn't much different\n"
  90"than a directory in /proc.\n");
  91}
  92
  93CONFIGFS_ATTR_RO(childless_, showme);
  94CONFIGFS_ATTR(childless_, storeme);
  95CONFIGFS_ATTR_RO(childless_, description);
  96
  97static struct configfs_attribute *childless_attrs[] = {
  98        &childless_attr_showme,
  99        &childless_attr_storeme,
 100        &childless_attr_description,
 101        NULL,
 102};
 103
 104static const struct config_item_type childless_type = {
 105        .ct_attrs       = childless_attrs,
 106        .ct_owner       = THIS_MODULE,
 107};
 108
 109static struct childless childless_subsys = {
 110        .subsys = {
 111                .su_group = {
 112                        .cg_item = {
 113                                .ci_namebuf = "01-childless",
 114                                .ci_type = &childless_type,
 115                        },
 116                },
 117        },
 118};
 119
 120
 121/* ----------------------------------------------------------------- */
 122
 123/*
 124 * 02-simple-children
 125 *
 126 * This example merely has a simple one-attribute child.  Note that
 127 * there is no extra attribute structure, as the child's attribute is
 128 * known from the get-go.  Also, there is no container for the
 129 * subsystem, as it has no attributes of its own.
 130 */
 131
 132struct simple_child {
 133        struct config_item item;
 134        int storeme;
 135};
 136
 137static inline struct simple_child *to_simple_child(struct config_item *item)
 138{
 139        return item ? container_of(item, struct simple_child, item) : NULL;
 140}
 141
 142static ssize_t simple_child_storeme_show(struct config_item *item, char *page)
 143{
 144        return sprintf(page, "%d\n", to_simple_child(item)->storeme);
 145}
 146
 147static ssize_t simple_child_storeme_store(struct config_item *item,
 148                const char *page, size_t count)
 149{
 150        struct simple_child *simple_child = to_simple_child(item);
 151        unsigned long tmp;
 152        char *p = (char *) page;
 153
 154        tmp = simple_strtoul(p, &p, 10);
 155        if (!p || (*p && (*p != '\n')))
 156                return -EINVAL;
 157
 158        if (tmp > INT_MAX)
 159                return -ERANGE;
 160
 161        simple_child->storeme = tmp;
 162
 163        return count;
 164}
 165
 166CONFIGFS_ATTR(simple_child_, storeme);
 167
 168static struct configfs_attribute *simple_child_attrs[] = {
 169        &simple_child_attr_storeme,
 170        NULL,
 171};
 172
 173static void simple_child_release(struct config_item *item)
 174{
 175        kfree(to_simple_child(item));
 176}
 177
 178static struct configfs_item_operations simple_child_item_ops = {
 179        .release                = simple_child_release,
 180};
 181
 182static const struct config_item_type simple_child_type = {
 183        .ct_item_ops    = &simple_child_item_ops,
 184        .ct_attrs       = simple_child_attrs,
 185        .ct_owner       = THIS_MODULE,
 186};
 187
 188
 189struct simple_children {
 190        struct config_group group;
 191};
 192
 193static inline struct simple_children *to_simple_children(struct config_item *item)
 194{
 195        return item ? container_of(to_config_group(item),
 196                        struct simple_children, group) : NULL;
 197}
 198
 199static struct config_item *simple_children_make_item(struct config_group *group,
 200                const char *name)
 201{
 202        struct simple_child *simple_child;
 203
 204        simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
 205        if (!simple_child)
 206                return ERR_PTR(-ENOMEM);
 207
 208        config_item_init_type_name(&simple_child->item, name,
 209                                   &simple_child_type);
 210
 211        simple_child->storeme = 0;
 212
 213        return &simple_child->item;
 214}
 215
 216static ssize_t simple_children_description_show(struct config_item *item,
 217                char *page)
 218{
 219        return sprintf(page,
 220"[02-simple-children]\n"
 221"\n"
 222"This subsystem allows the creation of child config_items.  These\n"
 223"items have only one attribute that is readable and writeable.\n");
 224}
 225
 226CONFIGFS_ATTR_RO(simple_children_, description);
 227
 228static struct configfs_attribute *simple_children_attrs[] = {
 229        &simple_children_attr_description,
 230        NULL,
 231};
 232
 233static void simple_children_release(struct config_item *item)
 234{
 235        kfree(to_simple_children(item));
 236}
 237
 238static struct configfs_item_operations simple_children_item_ops = {
 239        .release        = simple_children_release,
 240};
 241
 242/*
 243 * Note that, since no extra work is required on ->drop_item(),
 244 * no ->drop_item() is provided.
 245 */
 246static struct configfs_group_operations simple_children_group_ops = {
 247        .make_item      = simple_children_make_item,
 248};
 249
 250static const struct config_item_type simple_children_type = {
 251        .ct_item_ops    = &simple_children_item_ops,
 252        .ct_group_ops   = &simple_children_group_ops,
 253        .ct_attrs       = simple_children_attrs,
 254        .ct_owner       = THIS_MODULE,
 255};
 256
 257static struct configfs_subsystem simple_children_subsys = {
 258        .su_group = {
 259                .cg_item = {
 260                        .ci_namebuf = "02-simple-children",
 261                        .ci_type = &simple_children_type,
 262                },
 263        },
 264};
 265
 266
 267/* ----------------------------------------------------------------- */
 268
 269/*
 270 * 03-group-children
 271 *
 272 * This example reuses the simple_children group from above.  However,
 273 * the simple_children group is not the subsystem itself, it is a
 274 * child of the subsystem.  Creation of a group in the subsystem creates
 275 * a new simple_children group.  That group can then have simple_child
 276 * children of its own.
 277 */
 278
 279static struct config_group *group_children_make_group(
 280                struct config_group *group, const char *name)
 281{
 282        struct simple_children *simple_children;
 283
 284        simple_children = kzalloc(sizeof(struct simple_children),
 285                                  GFP_KERNEL);
 286        if (!simple_children)
 287                return ERR_PTR(-ENOMEM);
 288
 289        config_group_init_type_name(&simple_children->group, name,
 290                                    &simple_children_type);
 291
 292        return &simple_children->group;
 293}
 294
 295static ssize_t group_children_description_show(struct config_item *item,
 296                char *page)
 297{
 298        return sprintf(page,
 299"[03-group-children]\n"
 300"\n"
 301"This subsystem allows the creation of child config_groups.  These\n"
 302"groups are like the subsystem simple-children.\n");
 303}
 304
 305CONFIGFS_ATTR_RO(group_children_, description);
 306
 307static struct configfs_attribute *group_children_attrs[] = {
 308        &group_children_attr_description,
 309        NULL,
 310};
 311
 312/*
 313 * Note that, since no extra work is required on ->drop_item(),
 314 * no ->drop_item() is provided.
 315 */
 316static struct configfs_group_operations group_children_group_ops = {
 317        .make_group     = group_children_make_group,
 318};
 319
 320static const struct config_item_type group_children_type = {
 321        .ct_group_ops   = &group_children_group_ops,
 322        .ct_attrs       = group_children_attrs,
 323        .ct_owner       = THIS_MODULE,
 324};
 325
 326static struct configfs_subsystem group_children_subsys = {
 327        .su_group = {
 328                .cg_item = {
 329                        .ci_namebuf = "03-group-children",
 330                        .ci_type = &group_children_type,
 331                },
 332        },
 333};
 334
 335/* ----------------------------------------------------------------- */
 336
 337/*
 338 * We're now done with our subsystem definitions.
 339 * For convenience in this module, here's a list of them all.  It
 340 * allows the init function to easily register them.  Most modules
 341 * will only have one subsystem, and will only call register_subsystem
 342 * on it directly.
 343 */
 344static struct configfs_subsystem *example_subsys[] = {
 345        &childless_subsys.subsys,
 346        &simple_children_subsys,
 347        &group_children_subsys,
 348        NULL,
 349};
 350
 351static int __init configfs_example_init(void)
 352{
 353        int ret;
 354        int i;
 355        struct configfs_subsystem *subsys;
 356
 357        for (i = 0; example_subsys[i]; i++) {
 358                subsys = example_subsys[i];
 359
 360                config_group_init(&subsys->su_group);
 361                mutex_init(&subsys->su_mutex);
 362                ret = configfs_register_subsystem(subsys);
 363                if (ret) {
 364                        printk(KERN_ERR "Error %d while registering subsystem %s\n",
 365                               ret,
 366                               subsys->su_group.cg_item.ci_namebuf);
 367                        goto out_unregister;
 368                }
 369        }
 370
 371        return 0;
 372
 373out_unregister:
 374        for (i--; i >= 0; i--)
 375                configfs_unregister_subsystem(example_subsys[i]);
 376
 377        return ret;
 378}
 379
 380static void __exit configfs_example_exit(void)
 381{
 382        int i;
 383
 384        for (i = 0; example_subsys[i]; i++)
 385                configfs_unregister_subsystem(example_subsys[i]);
 386}
 387
 388module_init(configfs_example_init);
 389module_exit(configfs_example_exit);
 390MODULE_LICENSE("GPL");
 391