Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] configfs: Convenience macros for attribute definition.

Sysfs has the _ATTR() and _ATTR_RO() macros to make defining extended
form attributes easier. configfs should have something similiar.

- _CONFIGFS_ATTR() and _CONFIGFS_ATTR_RO() are the counterparts to the
sysfs macros.
- CONFIGFS_ATTR_STRUCT() creates the extended form attribute structure.
- CONFIGFS_ATTR_OPS() defines the show_attribute()/store_attribute()
operations that call the show()/store() operations of the extended
form configfs_attributes.

Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>

authored by

Joel Becker and committed by
Mark Fasheh
ecb3d28c 70526b67

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