diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-03 13:59:15 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-03 13:59:15 -0700 |
commit | d9b58ab789b053b70dc475f1efda124857f10aa2 (patch) | |
tree | f43c705e4417e65811de57f38b5a85cc9e7812d9 /lib | |
parent | 5264406cdb66c7003eb3edf53c9773b1b20611b9 (diff) | |
parent | c3497fd009ef2c59eea60d21c3ac22de3585ed7d (diff) |
Merge tag 'pull-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull copy_to_iter_mc fix from Al Viro:
"Backportable fix for copy_to_iter_mc() - the second part of iov_iter
work will pretty much overwrite this, but would be much harder to
backport"
* tag 'pull-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
fix short copy handling in copy_mc_pipe_to_iter()
Diffstat (limited to 'lib')
-rw-r--r-- | lib/iov_iter.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 58648fcd9a88..0e0be334dbee 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -521,6 +521,7 @@ static size_t copy_mc_pipe_to_iter(const void *addr, size_t bytes, struct pipe_inode_info *pipe = i->pipe; unsigned int p_mask = pipe->ring_size - 1; unsigned int i_head; + unsigned int valid = pipe->head; size_t n, off, xfer = 0; if (!sanity(i)) @@ -534,11 +535,17 @@ static size_t copy_mc_pipe_to_iter(const void *addr, size_t bytes, rem = copy_mc_to_kernel(p + off, addr + xfer, chunk); chunk -= rem; kunmap_local(p); - i->head = i_head; - i->iov_offset = off + chunk; - xfer += chunk; - if (rem) + if (chunk) { + i->head = i_head; + i->iov_offset = off + chunk; + xfer += chunk; + valid = i_head + 1; + } + if (rem) { + pipe->bufs[i_head & p_mask].len -= rem; + pipe_discard_from(pipe, valid); break; + } n -= chunk; off = 0; i_head++; |