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 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;  |