configfs: add show and store methods to struct configfs_attribute

Add methods to struct configfs_attribute to directly show and store
attributes without adding boilerplate code to every user.  In addition
to the methods this also adds 3 helper macros to define read/write,
read-only and write-only attributes with a single line of code.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Nicholas Bellinger <nab@linux-iscsi.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
Christoph Hellwig 2015-10-03 15:32:37 +02:00 committed by Nicholas Bellinger
parent 6ff33f3902
commit 870823e629
2 changed files with 39 additions and 5 deletions

View File

@ -74,7 +74,11 @@ static int fill_read_buffer(struct dentry * dentry, struct configfs_buffer * buf
if (!buffer->page) if (!buffer->page)
return -ENOMEM; return -ENOMEM;
count = ops->show_attribute(item,attr,buffer->page); if (ops->show_attribute)
count = ops->show_attribute(item, attr, buffer->page);
else
count = attr->show(item, buffer->page);
buffer->needs_read_fill = 0; buffer->needs_read_fill = 0;
BUG_ON(count > (ssize_t)SIMPLE_ATTR_SIZE); BUG_ON(count > (ssize_t)SIMPLE_ATTR_SIZE);
if (count >= 0) if (count >= 0)
@ -173,7 +177,9 @@ flush_write_buffer(struct dentry * dentry, struct configfs_buffer * buffer, size
struct config_item * item = to_item(dentry->d_parent); struct config_item * item = to_item(dentry->d_parent);
struct configfs_item_operations * ops = buffer->ops; struct configfs_item_operations * ops = buffer->ops;
return ops->store_attribute(item,attr,buffer->page,count); if (ops->store_attribute)
return ops->store_attribute(item, attr, buffer->page, count);
return attr->store(item, buffer->page, count);
} }
@ -237,8 +243,8 @@ static int check_perm(struct inode * inode, struct file * file)
* and we must have a store method. * and we must have a store method.
*/ */
if (file->f_mode & FMODE_WRITE) { if (file->f_mode & FMODE_WRITE) {
if (!(inode->i_mode & S_IWUGO) ||
if (!(inode->i_mode & S_IWUGO) || !ops->store_attribute) (!ops->store_attribute && !attr->store))
goto Eaccess; goto Eaccess;
} }
@ -248,7 +254,8 @@ static int check_perm(struct inode * inode, struct file * file)
* must be a show method for it. * must be a show method for it.
*/ */
if (file->f_mode & FMODE_READ) { if (file->f_mode & FMODE_READ) {
if (!(inode->i_mode & S_IRUGO) || !ops->show_attribute) if (!(inode->i_mode & S_IRUGO) ||
(!ops->show_attribute && !attr->show))
goto Eaccess; goto Eaccess;
} }

View File

@ -125,8 +125,35 @@ struct configfs_attribute {
const char *ca_name; const char *ca_name;
struct module *ca_owner; struct module *ca_owner;
umode_t ca_mode; umode_t ca_mode;
ssize_t (*show)(struct config_item *, char *);
ssize_t (*store)(struct config_item *, const char *, size_t);
}; };
#define CONFIGFS_ATTR(_pfx, _name) \
static struct configfs_attribute _pfx##attr_##_name = { \
.ca_name = __stringify(_name), \
.ca_mode = S_IRUGO | S_IWUSR, \
.ca_owner = THIS_MODULE, \
.show = _pfx##_name##_show, \
.store = _pfx##_name##_store, \
}
#define CONFIGFS_ATTR_RO(_pfx, _name) \
static struct configfs_attribute _pfx##attr_##_name = { \
.ca_name = __stringify(_name), \
.ca_mode = S_IRUGO, \
.ca_owner = THIS_MODULE, \
.show = _pfx##_name##_show, \
}
#define CONFIGFS_ATTR_WO(_pfx, _name) \
static struct configfs_attribute _pfx##attr_##_name = { \
.ca_name = __stringify(_name), \
.ca_mode = S_IWUSR, \
.ca_owner = THIS_MODULE, \
.store = _pfx##_name##_store, \
}
/* /*
* Users often need to create attribute structures for their configurable * Users often need to create attribute structures for their configurable
* attributes, containing a configfs_attribute member and function pointers * attributes, containing a configfs_attribute member and function pointers