diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 11:32:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 11:32:11 -0400 |
commit | 6c5daf012c9155aafd2c7973e4278766c30dfad0 (patch) | |
tree | 33959d7b36d03e1610615641a2940cb2de5e8603 /fs/libfs.c | |
parent | 6d39b27f0ac7e805ae3bd9efa51d7da04bec0360 (diff) | |
parent | c08d3b0e33edce28e9cfa7b64f7fe5bdeeb29248 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
truncate: use new helpers
truncate: new helpers
fs: fix overflow in sys_mount() for in-kernel calls
fs: Make unload_nls() NULL pointer safe
freeze_bdev: grab active reference to frozen superblocks
freeze_bdev: kill bd_mount_sem
exofs: remove BKL from super operations
fs/romfs: correct error-handling code
vfs: seq_file: add helpers for data filling
vfs: remove redundant position check in do_sendfile
vfs: change sb->s_maxbytes to a loff_t
vfs: explicitly cast s_maxbytes in fiemap_check_ranges
libfs: return error code on failed attr set
seq_file: return a negative error code when seq_path_root() fails.
vfs: optimize touch_time() too
vfs: optimization for touch_atime()
vfs: split generic_forget_inode() so that hugetlbfs does not have to copy it
fs/inode.c: add dev-id and inode number for debugging in init_special_inode()
libfs: make simple_read_from_buffer conventional
Diffstat (limited to 'fs/libfs.c')
-rw-r--r-- | fs/libfs.c | 13 |
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 */ | ||
742 | out: | 747 | out: |
743 | mutex_unlock(&attr->mutex); | 748 | mutex_unlock(&attr->mutex); |
744 | return ret; | 749 | return ret; |