diff options
Diffstat (limited to 'fs/libfs.c')
-rw-r--r-- | fs/libfs.c | 21 |
1 files changed, 13 insertions, 8 deletions
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) | |||
583 | /* Simple attribute files */ | 583 | /* Simple attribute files */ |
584 | 584 | ||
585 | struct simple_attr { | 585 | struct simple_attr { |
586 | u64 (*get)(void *); | 586 | int (*get)(void *, u64 *); |
587 | void (*set)(void *, u64); | 587 | int (*set)(void *, u64); |
588 | char get_buf[24]; /* enough to store a u64 and "\n\0" */ | 588 | char get_buf[24]; /* enough to store a u64 and "\n\0" */ |
589 | char set_buf[24]; | 589 | char set_buf[24]; |
590 | void *data; | 590 | void *data; |
@@ -595,7 +595,7 @@ struct simple_attr { | |||
595 | /* simple_attr_open is called by an actual attribute open file operation | 595 | /* simple_attr_open is called by an actual attribute open file operation |
596 | * to set the attribute specific access operations. */ | 596 | * to set the attribute specific access operations. */ |
597 | int simple_attr_open(struct inode *inode, struct file *file, | 597 | int simple_attr_open(struct inode *inode, struct file *file, |
598 | u64 (*get)(void *), void (*set)(void *, u64), | 598 | int (*get)(void *, u64 *), int (*set)(void *, u64), |
599 | const char *fmt) | 599 | const char *fmt) |
600 | { | 600 | { |
601 | struct simple_attr *attr; | 601 | struct simple_attr *attr; |
@@ -635,14 +635,20 @@ ssize_t simple_attr_read(struct file *file, char __user *buf, | |||
635 | return -EACCES; | 635 | return -EACCES; |
636 | 636 | ||
637 | mutex_lock(&attr->mutex); | 637 | mutex_lock(&attr->mutex); |
638 | if (*ppos) /* continued read */ | 638 | if (*ppos) { /* continued read */ |
639 | size = strlen(attr->get_buf); | 639 | size = strlen(attr->get_buf); |
640 | else /* first read */ | 640 | } else { /* first read */ |
641 | u64 val; | ||
642 | ret = attr->get(attr->data, &val); | ||
643 | if (ret) | ||
644 | goto out; | ||
645 | |||
641 | size = scnprintf(attr->get_buf, sizeof(attr->get_buf), | 646 | size = scnprintf(attr->get_buf, sizeof(attr->get_buf), |
642 | attr->fmt, | 647 | attr->fmt, (unsigned long long)val); |
643 | (unsigned long long)attr->get(attr->data)); | 648 | } |
644 | 649 | ||
645 | ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size); | 650 | ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size); |
651 | out: | ||
646 | mutex_unlock(&attr->mutex); | 652 | mutex_unlock(&attr->mutex); |
647 | return ret; | 653 | return ret; |
648 | } | 654 | } |
@@ -657,7 +663,6 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf, | |||
657 | ssize_t ret; | 663 | ssize_t ret; |
658 | 664 | ||
659 | attr = file->private_data; | 665 | attr = file->private_data; |
660 | |||
661 | if (!attr->set) | 666 | if (!attr->set) |
662 | return -EACCES; | 667 | return -EACCES; |
663 | 668 | ||