Commit ecb3d28c authored by Joel Becker's avatar Joel Becker Committed by Mark Fasheh

[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: default avatarJoel Becker <joel.becker@oracle.com>
Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
parent 70526b67
......@@ -311,9 +311,20 @@ the subsystem must be ready for it.
[An Example]
The best example of these basic concepts is the simple_children
subsystem/group and the simple_child item in configfs_example.c It
shows a trivial object displaying and storing an attribute, and a simple
group creating and destroying these children.
subsystem/group and the simple_child item in configfs_example_explicit.c
and configfs_example_macros.c. It shows a trivial object displaying and
storing an attribute, and a simple group creating and destroying these
children.
The only difference between configfs_example_explicit.c and
configfs_example_macros.c is how the attributes of the childless item
are defined. The childless item has extended attributes, each with
their own show()/store() operation. This follows a convention commonly
used in sysfs. configfs_example_explicit.c creates these attributes
by explicitly defining the structures involved. Conversely
configfs_example_macros.c uses some convenience macros from configfs.h
to define the attributes. These macros are similar to their sysfs
counterparts.
[Hierarchy Navigation and the Subsystem Mutex]
......
/*
* vim: noexpandtab ts=8 sts=0 sw=8:
*
* configfs_example.c - This file is a demonstration module containing
* a number of configfs subsystems.
* configfs_example_explicit.c - This file is a demonstration module
* containing a number of configfs subsystems. It explicitly defines
* each structure without using the helper macros defined in
* configfs.h.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
......@@ -281,7 +283,6 @@ static struct config_item *simple_children_make_item(struct config_group *group,
if (!simple_child)
return ERR_PTR(-ENOMEM);
config_item_init_type_name(&simple_child->item, name,
&simple_child_type);
......@@ -302,8 +303,8 @@ static struct configfs_attribute *simple_children_attrs[] = {
};
static ssize_t simple_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[02-simple-children]\n"
......@@ -318,7 +319,7 @@ static void simple_children_release(struct config_item *item)
}
static struct configfs_item_operations simple_children_item_ops = {
.release = simple_children_release,
.release = simple_children_release,
.show_attribute = simple_children_attr_show,
};
......@@ -368,7 +369,6 @@ static struct config_group *group_children_make_group(struct config_group *group
if (!simple_children)
return ERR_PTR(-ENOMEM);
config_group_init_type_name(&simple_children->group, name,
&simple_children_type);
......@@ -387,8 +387,8 @@ static struct configfs_attribute *group_children_attrs[] = {
};
static ssize_t group_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[03-group-children]\n"
......
This diff is collapsed.
......@@ -130,8 +130,25 @@ struct configfs_attribute {
/*
* Users often need to create attribute structures for their configurable
* attributes, containing a configfs_attribute member and function pointers
* for the show() and store() operations on that attribute. They can use
* this macro (similar to sysfs' __ATTR) to make defining attributes easier.
* for the show() and store() operations on that attribute. If they don't
* need anything else on the extended attribute structure, they can use
* this macro to define it The argument _item is the name of the
* config_item structure.
*/
#define CONFIGFS_ATTR_STRUCT(_item) \
struct _item##_attribute { \
struct configfs_attribute attr; \
ssize_t (*show)(struct _item *, char *); \
ssize_t (*store)(struct _item *, const char *, size_t); \
}
/*
* With the extended attribute structure, users can use this macro
* (similar to sysfs' __ATTR) to make defining attributes easier.
* An example:
* #define MYITEM_ATTR(_name, _mode, _show, _store) \
* struct myitem_attribute childless_attr_##_name = \
* __CONFIGFS_ATTR(_name, _mode, _show, _store)
*/
#define __CONFIGFS_ATTR(_name, _mode, _show, _store) \
{ \
......@@ -143,6 +160,52 @@ struct configfs_attribute {
.show = _show, \
.store = _store, \
}
/* Here is a readonly version, only requiring a show() operation */
#define __CONFIGFS_ATTR_RO(_name, _show) \
{ \
.attr = { \
.ca_name = __stringify(_name), \
.ca_mode = 0444, \
.ca_owner = THIS_MODULE, \
}, \
.show = _show, \
}
/*
* With these extended attributes, the simple show_attribute() and
* store_attribute() operations need to call the show() and store() of the
* attributes. This is a common pattern, so we provide a macro to define
* them. The argument _item is the name of the config_item structure.
* This macro expects the attributes to be named "struct <name>_attribute"
* and the function to_<name>() to exist;
*/
#define CONFIGFS_ATTR_OPS(_item) \
static ssize_t _item##_attr_show(struct config_item *item, \
struct configfs_attribute *attr, \
char *page) \
{ \
struct _item *_item = to_##_item(item); \
struct _item##_attribute *_item##_attr = \
container_of(attr, struct _item##_attribute, attr); \
ssize_t ret = 0; \
\
if (_item##_attr->show) \
ret = _item##_attr->show(_item, page); \
return ret; \
} \
static ssize_t _item##_attr_store(struct config_item *item, \
struct configfs_attribute *attr, \
const char *page, size_t count) \
{ \
struct _item *_item = to_##_item(item); \
struct _item##_attribute *_item##_attr = \
container_of(attr, struct _item##_attribute, attr); \
ssize_t ret = -EINVAL; \
\
if (_item##_attr->store) \
ret = _item##_attr->store(_item, page, count); \
return ret; \
}
/*
* If allow_link() exists, the item can symlink(2) out to other
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment