aboutsummaryrefslogtreecommitdiffstats
path: root/fs/libfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/libfs.c')
-rw-r--r--fs/libfs.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/fs/libfs.c b/fs/libfs.c
index dcec3d3ea64f..219576c52d80 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -527,14 +527,18 @@ ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos,
527 const void *from, size_t available) 527 const void *from, size_t available)
528{ 528{
529 loff_t pos = *ppos; 529 loff_t pos = *ppos;
530 size_t ret;
531
530 if (pos < 0) 532 if (pos < 0)
531 return -EINVAL; 533 return -EINVAL;
532 if (pos >= available) 534 if (pos >= available || !count)
533 return 0; 535 return 0;
534 if (count > available - pos) 536 if (count > available - pos)
535 count = available - pos; 537 count = available - pos;
536 if (copy_to_user(to, from + pos, count)) 538 ret = copy_to_user(to, from + pos, count);
539 if (ret == count)
537 return -EFAULT; 540 return -EFAULT;
541 count -= ret;
538 *ppos = pos + count; 542 *ppos = pos + count;
539 return count; 543 return count;
540} 544}
@@ -735,10 +739,11 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf,
735 if (copy_from_user(attr->set_buf, buf, size)) 739 if (copy_from_user(attr->set_buf, buf, size))
736 goto out; 740 goto out;
737 741
738 ret = len; /* claim we got the whole input */
739 attr->set_buf[size] = '\0'; 742 attr->set_buf[size] = '\0';
740 val = simple_strtol(attr->set_buf, NULL, 0); 743 val = simple_strtol(attr->set_buf, NULL, 0);
741 attr->set(attr->data, val); 744 ret = attr->set(attr->data, val);
745 if (ret == 0)
746 ret = len; /* on success, claim we got the whole input */
742out: 747out:
743 mutex_unlock(&attr->mutex); 748 mutex_unlock(&attr->mutex);
744 return ret; 749 return ret;