From 8b88b0998e35d239e74446cc30f354bdab86df89 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 8 Feb 2008 04:20:26 -0800 Subject: libfs: allow error return from simple attributes Sometimes simple attributes might need to return an error, e.g. for acquiring a mutex interruptibly. In fact we have that situation in spufs already which is the original user of the simple attributes. This patch merged the temporarily forked attributes in spufs back into the main ones and allows to return errors. [akpm@linux-foundation.org: build fix] Signed-off-by: Christoph Hellwig Cc: Cc: Arnd Bergmann Cc: Greg KH Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/libfs.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'fs/libfs.c') diff --git a/fs/libfs.c b/fs/libfs.c index 5523bde9638..2319415ddb5 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -583,8 +583,8 @@ int simple_transaction_release(struct inode *inode, struct file *file) /* Simple attribute files */ struct simple_attr { - u64 (*get)(void *); - void (*set)(void *, u64); + int (*get)(void *, u64 *); + int (*set)(void *, u64); char get_buf[24]; /* enough to store a u64 and "\n\0" */ char set_buf[24]; void *data; @@ -595,7 +595,7 @@ struct simple_attr { /* simple_attr_open is called by an actual attribute open file operation * to set the attribute specific access operations. */ int simple_attr_open(struct inode *inode, struct file *file, - u64 (*get)(void *), void (*set)(void *, u64), + int (*get)(void *, u64 *), int (*set)(void *, u64), const char *fmt) { struct simple_attr *attr; @@ -635,14 +635,20 @@ ssize_t simple_attr_read(struct file *file, char __user *buf, return -EACCES; mutex_lock(&attr->mutex); - if (*ppos) /* continued read */ + if (*ppos) { /* continued read */ size = strlen(attr->get_buf); - else /* first read */ + } else { /* first read */ + u64 val; + ret = attr->get(attr->data, &val); + if (ret) + goto out; + size = scnprintf(attr->get_buf, sizeof(attr->get_buf), - attr->fmt, - (unsigned long long)attr->get(attr->data)); + attr->fmt, (unsigned long long)val); + } ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size); +out: mutex_unlock(&attr->mutex); return ret; } @@ -657,7 +663,6 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf, ssize_t ret; attr = file->private_data; - if (!attr->set) return -EACCES; -- cgit v1.2.3