mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-07 13:53:24 +00:00
backportable fix for copy_to_iter_mc() - the second part of
iov_iter work will pretty much overwrite that one, but it's much harder to backport. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQQqUNBr3gm4hGXdBJlZ7Krx/gZQ6wUCYurHhgAKCRBZ7Krx/gZQ 6+cgAP9XLVFQn0UE1e1JTOitdC/pqjBDMUDQ7SDazrmiVWoMcAEAm+PJSl7GVvMi fo3fIlaullRT3DjCidAmbbaOOZqkmgA= =z+N2 -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
d9b58ab789
@ -229,6 +229,15 @@ static inline bool pipe_buf_try_steal(struct pipe_inode_info *pipe,
|
||||
return buf->ops->try_steal(pipe, buf);
|
||||
}
|
||||
|
||||
static inline void pipe_discard_from(struct pipe_inode_info *pipe,
|
||||
unsigned int old_head)
|
||||
{
|
||||
unsigned int mask = pipe->ring_size - 1;
|
||||
|
||||
while (pipe->head > old_head)
|
||||
pipe_buf_release(pipe, &pipe->bufs[--pipe->head & mask]);
|
||||
}
|
||||
|
||||
/* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual
|
||||
memory allocation, whereas PIPE_BUF makes atomicity guarantees. */
|
||||
#define PIPE_SIZE PAGE_SIZE
|
||||
|
@ -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++;
|
||||
|
Loading…
Reference in New Issue
Block a user