diff options
author | Abhi Das <adas@redhat.com> | 2016-11-17 06:44:23 +0300 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-11-17 08:00:48 +0300 |
commit | 680bb946a1ae04fe0ff369a4965f76b48c07dc54 (patch) | |
tree | be2ca455a6186b86a08e3ab1c22d49748cc6ed75 /lib/iov_iter.c | |
parent | 4a59015372840a6fc35d7fd40638a9d5dc3ec958 (diff) | |
download | linux-680bb946a1ae04fe0ff369a4965f76b48c07dc54.tar.xz |
fix iov_iter_advance() for ITER_PIPE
iov_iter_advance() needs to decrement iter->count by the number of
bytes we'd moved beyond. Normal flavours do that, but ITER_PIPE
doesn't and ITER_PIPE generic_file_read_iter() for O_DIRECT files
ends up with a bogus fallback to page cache read, resulting in incorrect
values for file offset and bytes read.
Signed-off-by: Abhi Das <adas@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'lib/iov_iter.c')
-rw-r--r-- | lib/iov_iter.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index f0c7f1481bae..f2bd21b93dfc 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -683,10 +683,11 @@ static void pipe_advance(struct iov_iter *i, size_t size) struct pipe_inode_info *pipe = i->pipe; struct pipe_buffer *buf; int idx = i->idx; - size_t off = i->iov_offset; + size_t off = i->iov_offset, orig_sz; if (unlikely(i->count < size)) size = i->count; + orig_sz = size; if (size) { if (off) /* make it relative to the beginning of buffer */ @@ -713,6 +714,7 @@ static void pipe_advance(struct iov_iter *i, size_t size) pipe->nrbufs--; } } + i->count -= orig_sz; } void iov_iter_advance(struct iov_iter *i, size_t size) |