linux/Documentation/filesystems/configfs/configfs_example_explicit.c
<<
>>
Prefs
   1/*
   2 * vim: noexpandtab ts=8 sts=0 sw=8:
   3 *
   4 * configfs_example_explicit.c - This file is a demonstration module
   5 *      containing a number of configfs subsystems.  It explicitly defines
   6 *      each structure without using the helper macros defined in
   7 *      configfs.h.
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public
  11 * License as published by the Free Software Foundation; either
  12 * version 2 of the License, or (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public
  20 * License along with this program; if not, write to the
  21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  22 * Boston, MA 021110-1307, USA.
  23 *
  24 * Based on sysfs:
  25 *      sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
  26 *
  27 * configfs Copyright (C) 2005 Oracle.  All rights reserved.
  28 */
  29
  30#include <linux/init.h>
  31#include <linux/module.h>
  32#include <linux/slab.h>
  33
  34#include <linux/configfs.h>
  35
  36
  37
  38/*
  39 * 01-childless
  40 *
  41 * This first example is a childless subsystem.  It cannot create
  42 * any config_items.  It just has attributes.
  43 *
  44 * Note that we are enclosing the configfs_subsystem inside a container.
  45 * This is not necessary if a subsystem has no attributes directly
  46 * on the subsystem.  See the next example, 02-simple-children, for
  47 * such a subsystem.
  48 */
  49
  50struct childless {
  51        struct configfs_subsystem subsys;
  52        int showme;
  53        int storeme;
  54};
  55
  56struct childless_attribute {
  57        struct configfs_attribute attr;
  58        ssize_t (*show)(struct childless *, char *);
  59        ssize_t (*store)(struct childless *, const char *, size_t);
  60};
  61
  62static inline struct childless *to_childless(struct config_item *item)
  63{
  64        return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
  65}
  66
  67static ssize_t childless_showme_read(struct childless *childless,
  68                                     char *page)
  69{
  70        ssize_t pos;
  71
  72        pos = sprintf(page, "%d\n", childless->showme);
  73        childless->showme++;
  74
  75        return pos;
  76}
  77
  78static ssize_t childless_storeme_read(struct childless *childless,
  79                                      char *page)
  80{
  81        return sprintf(page, "%d\n", childless->storeme);
  82}
  83
  84static ssize_t childless_storeme_write(struct childless *childless,
  85                                       const char *page,
  86                                       size_t count)
  87{
  88        unsigned long tmp;
  89        char *p = (char *) page;
  90
  91        tmp = simple_strtoul(p, &p, 10);
  92        if ((*p != '\0') && (*p != '\n'))
  93                return -EINVAL;
  94
  95        if (tmp > INT_MAX)
  96                return -ERANGE;
  97
  98        childless->storeme = tmp;
  99
 100        return count;
 101}
 102
 103static ssize_t childless_description_read(struct childless *childless,
 104                                          char *page)
 105{
 106        return sprintf(page,
 107"[01-childless]\n"
 108"\n"
 109"The childless subsystem is the simplest possible subsystem in\n"
 110"configfs.  It does not support the creation of child config_items.\n"
 111"It only has a few attributes.  In fact, it isn't much different\n"
 112"than a directory in /proc.\n");
 113}
 114
 115static struct childless_attribute childless_attr_showme = {
 116        .attr   = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO },
 117        .show   = childless_showme_read,
 118};
 119static struct childless_attribute childless_attr_storeme = {
 120        .attr   = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR },
 121        .show   = childless_storeme_read,
 122        .store  = childless_storeme_write,
 123};
 124static struct childless_attribute childless_attr_description = {
 125        .attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO },
 126        .show = childless_description_read,
 127};
 128
 129static struct configfs_attribute *childless_attrs[] = {
 130        &childless_attr_showme.attr,
 131        &childless_attr_storeme.attr,
 132        &childless_attr_description.attr,
 133        NULL,
 134};
 135
 136static ssize_t childless_attr_show(struct config_item *item,
 137                                   struct configfs_attribute *attr,
 138                                   char *page)
 139{
 140        struct childless *childless = to_childless(item);
 141        struct childless_attribute *childless_attr =
 142                container_of(attr, struct childless_attribute, attr);
 143        ssize_t ret = 0;
 144
 145        if (childless_attr->show)
 146                ret = childless_attr->show(childless, page);
 147        return ret;
 148}
 149
 150static ssize_t childless_attr_store(struct config_item *item,
 151                                    struct configfs_attribute *attr,
 152                                    const char *page, size_t count)
 153{
 154        struct childless *childless = to_childless(item);
 155        struct childless_attribute *childless_attr =
 156                container_of(attr, struct childless_attribute, attr);
 157        ssize_t ret = -EINVAL;
 158
 159        if (childless_attr->store)
 160                ret = childless_attr->store(childless, page, count);
 161        return ret;
 162}
 163
 164static struct configfs_item_operations childless_item_ops = {
 165        .show_attribute         = childless_attr_show,
 166        .store_attribute        = childless_attr_store,
 167};
 168
 169static struct config_item_type childless_type = {
 170        .ct_item_ops    = &childless_item_ops,
 171        .ct_attrs       = childless_attrs,
 172        .ct_owner       = THIS_MODULE,
 173};
 174
 175static struct childless childless_subsys = {
 176        .subsys = {
 177                .su_group = {
 178                        .cg_item = {
 179                                .ci_namebuf = "01-childless",
 180                                .ci_type = &childless_type,
 181                        },
 182                },
 183        },
 184};
 185
 186
 187/* ----------------------------------------------------------------- */
 188
 189/*
 190 * 02-simple-children
 191 *
 192 * This example merely has a simple one-attribute child.  Note that
 193 * there is no extra attribute structure, as the child's attribute is
 194 * known from the get-go.  Also, there is no container for the
 195 * subsystem, as it has no attributes of its own.
 196 */
 197
 198struct simple_child {
 199        struct config_item item;
 200        int storeme;
 201};
 202
 203static inline struct simple_child *to_simple_child(struct config_item *item)
 204{
 205        return item ? container_of(item, struct simple_child, item) : NULL;
 206}
 207
 208static struct configfs_attribute simple_child_attr_storeme = {
 209        .ca_owner = THIS_MODULE,
 210        .ca_name = "storeme",
 211        .ca_mode = S_IRUGO | S_IWUSR,
 212};
 213
 214static struct configfs_attribute *simple_child_attrs[] = {
 215        &simple_child_attr_storeme,
 216        NULL,
 217};
 218
 219static ssize_t simple_child_attr_show(struct config_item *item,
 220                                      struct configfs_attribute *attr,
 221                                      char *page)
 222{
 223        ssize_t count;
 224        struct simple_child *simple_child = to_simple_child(item);
 225
 226        count = sprintf(page, "%d\n", simple_child->storeme);
 227
 228        return count;
 229}
 230
 231static ssize_t simple_child_attr_store(struct config_item *item,
 232                                       struct configfs_attribute *attr,
 233                                       const char *page, size_t count)
 234{
 235        struct simple_child *simple_child = to_simple_child(item);
 236        unsigned long tmp;
 237        char *p = (char *) page;
 238
 239        tmp = simple_strtoul(p, &p, 10);
 240        if (!p || (*p && (*p != '\n')))
 241                return -EINVAL;
 242
 243        if (tmp > INT_MAX)
 244                return -ERANGE;
 245
 246        simple_child->storeme = tmp;
 247
 248        return count;
 249}
 250
 251static void simple_child_release(struct config_item *item)
 252{
 253        kfree(to_simple_child(item));
 254}
 255
 256static struct configfs_item_operations simple_child_item_ops = {
 257        .release                = simple_child_release,
 258        .show_attribute         = simple_child_attr_show,
 259        .store_attribute        = simple_child_attr_store,
 260};
 261
 262static struct config_item_type simple_child_type = {
 263        .ct_item_ops    = &simple_child_item_ops,
 264        .ct_attrs       = simple_child_attrs,
 265        .ct_owner       = THIS_MODULE,
 266};
 267
 268
 269struct simple_children {
 270        struct config_group group;
 271};
 272
 273static inline struct simple_children *to_simple_children(struct config_item *item)
 274{
 275        return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
 276}
 277
 278static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
 279{
 280        struct simple_child *simple_child;
 281
 282        simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
 283        if (!simple_child)
 284                return ERR_PTR(-ENOMEM);
 285
 286        config_item_init_type_name(&simple_child->item, name,
 287                                   &simple_child_type);
 288
 289        simple_child->storeme = 0;
 290
 291        return &simple_child->item;
 292}
 293
 294static struct configfs_attribute simple_children_attr_description = {
 295        .ca_owner = THIS_MODULE,
 296        .ca_name = "description",
 297        .ca_mode = S_IRUGO,
 298};
 299
 300static struct configfs_attribute *simple_children_attrs[] = {
 301        &simple_children_attr_description,
 302        NULL,
 303};
 304
 305static ssize_t simple_children_attr_show(struct config_item *item,
 306                                         struct configfs_attribute *attr,
 307                                         char *page)
 308{
 309        return sprintf(page,
 310"[02-simple-children]\n"
 311"\n"
 312"This subsystem allows the creation of child config_items.  These\n"
 313"items have only one attribute that is readable and writeable.\n");
 314}
 315
 316static void simple_children_release(struct config_item *item)
 317{
 318        kfree(to_simple_children(item));
 319}
 320
 321static struct configfs_item_operations simple_children_item_ops = {
 322        .release        = simple_children_release,
 323        .show_attribute = simple_children_attr_show,
 324};
 325
 326/*
 327 * Note that, since no extra work is required on ->drop_item(),
 328 * no ->drop_item() is provided.
 329 */
 330static struct configfs_group_operations simple_children_group_ops = {
 331        .make_item      = simple_children_make_item,
 332};
 333
 334static struct config_item_type simple_children_type = {
 335        .ct_item_ops    = &simple_children_item_ops,
 336        .ct_group_ops   = &simple_children_group_ops,
 337        .ct_attrs       = simple_children_attrs,
 338        .ct_owner       = THIS_MODULE,
 339};
 340
 341static struct configfs_subsystem simple_children_subsys = {
 342        .su_group = {
 343                .cg_item = {
 344                        .ci_namebuf = "02-simple-children",
 345                        .ci_type = &simple_children_type,
 346                },
 347        },
 348};
 349
 350
 351/* ----------------------------------------------------------------- */
 352
 353/*
 354 * 03-group-children
 355 *
 356 * This example reuses the simple_children group from above.  However,
 357 * the simple_children group is not the subsystem itself, it is a
 358 * child of the subsystem.  Creation of a group in the subsystem creates
 359 * a new simple_children group.  That group can then have simple_child
 360 * children of its own.
 361 */
 362
 363static struct config_group *group_children_make_group(struct config_group *group, const char *name)
 364{
 365        struct simple_children *simple_children;
 366
 367        simple_children = kzalloc(sizeof(struct simple_children),
 368                                  GFP_KERNEL);
 369        if (!simple_children)
 370                return ERR_PTR(-ENOMEM);
 371
 372        config_group_init_type_name(&simple_children->group, name,
 373                                    &simple_children_type);
 374
 375        return &simple_children->group;
 376}
 377
 378static struct configfs_attribute group_children_attr_description = {
 379        .ca_owner = THIS_MODULE,
 380        .ca_name = "description",
 381        .ca_mode = S_IRUGO,
 382};
 383
 384static struct configfs_attribute *group_children_attrs[] = {
 385        &group_children_attr_description,
 386        NULL,
 387};
 388
 389static ssize_t group_children_attr_show(struct config_item *item,
 390                                        struct configfs_attribute *attr,
 391                                        char *page)
 392{
 393        return sprintf(page,
 394"[03-group-children]\n"
 395"\n"
 396"This subsystem allows the creation of child config_groups.  These\n"
 397"groups are like the subsystem simple-children.\n");
 398}
 399
 400static struct configfs_item_operations group_children_item_ops = {
 401        .show_attribute = group_children_attr_show,
 402};
 403
 404/*
 405 * Note that, since no extra work is required on ->drop_item(),
 406 * no ->drop_item() is provided.
 407 */
 408static struct configfs_group_operations group_children_group_ops = {
 409        .make_group     = group_children_make_group,
 410};
 411
 412static struct config_item_type group_children_type = {
 413        .ct_item_ops    = &group_children_item_ops,
 414        .ct_group_ops   = &group_children_group_ops,
 415        .ct_attrs       = group_children_attrs,
 416        .ct_owner       = THIS_MODULE,
 417};
 418
 419static struct configfs_subsystem group_children_subsys = {
 420        .su_group = {
 421                .cg_item = {
 422                        .ci_namebuf = "03-group-children",
 423                        .ci_type = &group_children_type,
 424                },
 425        },
 426};
 427
 428/* ----------------------------------------------------------------- */
 429
 430/*
 431 * We're now done with our subsystem definitions.
 432 * For convenience in this module, here's a list of them all.  It
 433 * allows the init function to easily register them.  Most modules
 434 * will only have one subsystem, and will only call register_subsystem
 435 * on it directly.
 436 */
 437static struct configfs_subsystem *example_subsys[] = {
 438        &childless_subsys.subsys,
 439        &simple_children_subsys,
 440        &group_children_subsys,
 441        NULL,
 442};
 443
 444static int __init configfs_example_init(void)
 445{
 446        int ret;
 447        int i;
 448        struct configfs_subsystem *subsys;
 449
 450        for (i = 0; example_subsys[i]; i++) {
 451                subsys = example_subsys[i];
 452
 453                config_group_init(&subsys->su_group);
 454                mutex_init(&subsys->su_mutex);
 455                ret = configfs_register_subsystem(subsys);
 456                if (ret) {
 457                        printk(KERN_ERR "Error %d while registering subsystem %s\n",
 458                               ret,
 459                               subsys->su_group.cg_item.ci_namebuf);
 460                        goto out_unregister;
 461                }
 462        }
 463
 464        return 0;
 465
 466out_unregister:
 467        for (i--; i >= 0; i--)
 468                configfs_unregister_subsystem(example_subsys[i]);
 469
 470        return ret;
 471}
 472
 473static void __exit configfs_example_exit(void)
 474{
 475        int i;
 476
 477        for (i = 0; example_subsys[i]; i++)
 478                configfs_unregister_subsystem(example_subsys[i]);
 479}
 480
 481module_init(configfs_example_init);
 482module_exit(configfs_example_exit);
 483MODULE_LICENSE("GPL");
 484