diff options
-rw-r--r-- | fs/configfs/file.c | 17 | ||||
-rw-r--r-- | include/linux/configfs.h | 27 |
2 files changed, 39 insertions, 5 deletions
diff --git a/fs/configfs/file.c b/fs/configfs/file.c index 403269ffcdf3..106ca589e90a 100644 --- a/fs/configfs/file.c +++ b/fs/configfs/file.c @@ -74,7 +74,11 @@ static int fill_read_buffer(struct dentry * dentry, struct configfs_buffer * buf if (!buffer->page) 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; BUG_ON(count > (ssize_t)SIMPLE_ATTR_SIZE); 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 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. */ if (file->f_mode & FMODE_WRITE) { - - if (!(inode->i_mode & S_IWUGO) || !ops->store_attribute) + if (!(inode->i_mode & S_IWUGO) || + (!ops->store_attribute && !attr->store)) goto Eaccess; } @@ -248,7 +254,8 @@ static int check_perm(struct inode * inode, struct file * file) * must be a show method for it. */ 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; } diff --git a/include/linux/configfs.h b/include/linux/configfs.h index 63a36e89d0eb..85e9956a86de 100644 --- a/include/linux/configfs.h +++ b/include/linux/configfs.h @@ -125,8 +125,35 @@ struct configfs_attribute { const char *ca_name; struct module *ca_owner; 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 * attributes, containing a configfs_attribute member and function pointers |