diff options
Diffstat (limited to 'include/linux/configfs.h')
| -rw-r--r-- | include/linux/configfs.h | 68 |
1 files changed, 66 insertions, 2 deletions
diff --git a/include/linux/configfs.h b/include/linux/configfs.h index d62c19ff041c..7f627775c947 100644 --- a/include/linux/configfs.h +++ b/include/linux/configfs.h | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <linux/list.h> | 40 | #include <linux/list.h> |
| 41 | #include <linux/kref.h> | 41 | #include <linux/kref.h> |
| 42 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
| 43 | #include <linux/err.h> | ||
| 43 | 44 | ||
| 44 | #include <asm/atomic.h> | 45 | #include <asm/atomic.h> |
| 45 | 46 | ||
| @@ -129,8 +130,25 @@ struct configfs_attribute { | |||
| 129 | /* | 130 | /* |
| 130 | * Users often need to create attribute structures for their configurable | 131 | * Users often need to create attribute structures for their configurable |
| 131 | * attributes, containing a configfs_attribute member and function pointers | 132 | * attributes, containing a configfs_attribute member and function pointers |
| 132 | * for the show() and store() operations on that attribute. They can use | 133 | * for the show() and store() operations on that attribute. If they don't |
| 133 | * this macro (similar to sysfs' __ATTR) to make defining attributes easier. | 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) | ||
| 134 | */ | 152 | */ |
| 135 | #define __CONFIGFS_ATTR(_name, _mode, _show, _store) \ | 153 | #define __CONFIGFS_ATTR(_name, _mode, _show, _store) \ |
| 136 | { \ | 154 | { \ |
| @@ -142,6 +160,52 @@ struct configfs_attribute { | |||
| 142 | .show = _show, \ | 160 | .show = _show, \ |
| 143 | .store = _store, \ | 161 | .store = _store, \ |
| 144 | } | 162 | } |
| 163 | /* Here is a readonly version, only requiring a show() operation */ | ||
| 164 | #define __CONFIGFS_ATTR_RO(_name, _show) \ | ||
| 165 | { \ | ||
| 166 | .attr = { \ | ||
| 167 | .ca_name = __stringify(_name), \ | ||
| 168 | .ca_mode = 0444, \ | ||
| 169 | .ca_owner = THIS_MODULE, \ | ||
| 170 | }, \ | ||
| 171 | .show = _show, \ | ||
| 172 | } | ||
| 173 | |||
| 174 | /* | ||
| 175 | * With these extended attributes, the simple show_attribute() and | ||
| 176 | * store_attribute() operations need to call the show() and store() of the | ||
| 177 | * attributes. This is a common pattern, so we provide a macro to define | ||
| 178 | * them. The argument _item is the name of the config_item structure. | ||
| 179 | * This macro expects the attributes to be named "struct <name>_attribute" | ||
| 180 | * and the function to_<name>() to exist; | ||
| 181 | */ | ||
| 182 | #define CONFIGFS_ATTR_OPS(_item) \ | ||
| 183 | static ssize_t _item##_attr_show(struct config_item *item, \ | ||
| 184 | struct configfs_attribute *attr, \ | ||
| 185 | char *page) \ | ||
| 186 | { \ | ||
| 187 | struct _item *_item = to_##_item(item); \ | ||
| 188 | struct _item##_attribute *_item##_attr = \ | ||
| 189 | container_of(attr, struct _item##_attribute, attr); \ | ||
| 190 | ssize_t ret = 0; \ | ||
| 191 | \ | ||
| 192 | if (_item##_attr->show) \ | ||
| 193 | ret = _item##_attr->show(_item, page); \ | ||
| 194 | return ret; \ | ||
| 195 | } \ | ||
| 196 | static ssize_t _item##_attr_store(struct config_item *item, \ | ||
| 197 | struct configfs_attribute *attr, \ | ||
| 198 | const char *page, size_t count) \ | ||
| 199 | { \ | ||
| 200 | struct _item *_item = to_##_item(item); \ | ||
| 201 | struct _item##_attribute *_item##_attr = \ | ||
| 202 | container_of(attr, struct _item##_attribute, attr); \ | ||
| 203 | ssize_t ret = -EINVAL; \ | ||
| 204 | \ | ||
| 205 | if (_item##_attr->store) \ | ||
| 206 | ret = _item##_attr->store(_item, page, count); \ | ||
| 207 | return ret; \ | ||
| 208 | } | ||
| 145 | 209 | ||
| 146 | /* | 210 | /* |
| 147 | * If allow_link() exists, the item can symlink(2) out to other | 211 | * If allow_link() exists, the item can symlink(2) out to other |
