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: Miklos Szeredi <mszeredi@suse.cz> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
This commit is contained in:
Родитель
3e6c05052c
Коммит
1d862f4122
13
fs/pipe.c
13
fs/pipe.c
|
@ -1145,13 +1145,20 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages)
|
|||
* and adjust the indexes.
|
||||
*/
|
||||
if (pipe->nrbufs) {
|
||||
const unsigned int tail = pipe->nrbufs & (pipe->buffers - 1);
|
||||
const unsigned int head = pipe->nrbufs - tail;
|
||||
unsigned int 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)
|
||||
memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer));
|
||||
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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче