diff options
author | Steven Rostedt <rostedt@goodmis.org> | 2009-09-18 16:05:42 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-09-24 07:47:22 -0400 |
commit | 14be27460e4722d7135de3c46d043b4fc4382247 (patch) | |
tree | d7026e0e43c1f048f2a0f31a54beb93b91b5fb89 /fs/libfs.c | |
parent | 94a8d5caba74211ec76dac80fc6e2d5c391530df (diff) |
libfs: make simple_read_from_buffer conventional
Impact: have simple_read_from_buffer conform to standards
It was brought to my attention by Andrew Morton, Theodore Tso, and H.
Peter Anvin that a read from userspace should only return -EFAULT if
nothing was actually read.
Looking at the simple_read_from_buffer I noticed that this function does
not conform to that rule. This patch fixes that function.
[akpm@linux-foundation.org: simplification suggested by hpa]
[hpa@zytor.com: fix count==0 handling]
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Theodore Ts'o <tytso@mit.edu>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/libfs.c')
-rw-r--r-- | fs/libfs.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/fs/libfs.c b/fs/libfs.c index dcec3d3ea64f..662a28e4f667 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 | } |