Commit 1d862f41 authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Jens Axboe

pipe: fix pipe buffer resizing

pipe_set_size() needs to copy pipe bufs from the old circular buffer
to the new.

The current code gets this wrong in multiple ways, resulting in oops.

Test program is available here:
  http://www.kernel.org/pub/linux/kernel/people/mszeredi/piperesize/Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
Signed-off-by: default avatarJens Axboe <jaxboe@fusionio.com>
parent 3e6c0505
...@@ -1145,13 +1145,20 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages) ...@@ -1145,13 +1145,20 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages)
* and adjust the indexes. * and adjust the indexes.
*/ */
if (pipe->nrbufs) { if (pipe->nrbufs) {
const unsigned int tail = pipe->nrbufs & (pipe->buffers - 1); unsigned int tail;
const unsigned int head = pipe->nrbufs - tail; unsigned int head;
tail = pipe->curbuf + pipe->nrbufs;
if (tail < pipe->buffers)
tail = 0;
else
tail &= (pipe->buffers - 1);
head = pipe->nrbufs - tail;
if (head) if (head)
memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer)); memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer));
if (tail) if (tail)
memcpy(bufs + head, pipe->bufs + pipe->curbuf, tail * sizeof(struct pipe_buffer)); memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer));
} }
pipe->curbuf = 0; pipe->curbuf = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment