summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/configfs/file.c17
-rw-r--r--include/linux/configfs.h27
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