diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/debugfs/file.c | 32 | ||||
-rw-r--r-- | fs/libfs.c | 21 |
2 files changed, 33 insertions, 20 deletions
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index fa6b7f7ff914..fddffe4851f5 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -56,13 +56,15 @@ const struct inode_operations debugfs_link_operations = { .follow_link = debugfs_follow_link, }; -static void debugfs_u8_set(void *data, u64 val) +static int debugfs_u8_set(void *data, u64 val) { *(u8 *)data = val; + return 0; } -static u64 debugfs_u8_get(void *data) +static int debugfs_u8_get(void *data, u64 *val) { - return *(u8 *)data; + *val = *(u8 *)data; + return 0; } DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n"); @@ -97,13 +99,15 @@ struct dentry *debugfs_create_u8(const char *name, mode_t mode, } EXPORT_SYMBOL_GPL(debugfs_create_u8); -static void debugfs_u16_set(void *data, u64 val) +static int debugfs_u16_set(void *data, u64 val) { *(u16 *)data = val; + return 0; } -static u64 debugfs_u16_get(void *data) +static int debugfs_u16_get(void *data, u64 *val) { - return *(u16 *)data; + *val = *(u16 *)data; + return 0; } DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n"); @@ -138,13 +142,15 @@ struct dentry *debugfs_create_u16(const char *name, mode_t mode, } EXPORT_SYMBOL_GPL(debugfs_create_u16); -static void debugfs_u32_set(void *data, u64 val) +static int debugfs_u32_set(void *data, u64 val) { *(u32 *)data = val; + return 0; } -static u64 debugfs_u32_get(void *data) +static int debugfs_u32_get(void *data, u64 *val) { - return *(u32 *)data; + *val = *(u32 *)data; + return 0; } DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n"); @@ -179,14 +185,16 @@ struct dentry *debugfs_create_u32(const char *name, mode_t mode, } EXPORT_SYMBOL_GPL(debugfs_create_u32); -static void debugfs_u64_set(void *data, u64 val) +static int debugfs_u64_set(void *data, u64 val) { *(u64 *)data = val; + return 0; } -static u64 debugfs_u64_get(void *data) +static int debugfs_u64_get(void *data, u64 *val) { - return *(u64 *)data; + *val = *(u64 *)data; + return 0; } DEFINE_SIMPLE_ATTRIBUTE(fops_u64, debugfs_u64_get, debugfs_u64_set, "%llu\n"); diff --git a/fs/libfs.c b/fs/libfs.c index 5523bde96387..2319415ddb5e 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; |