diff options
Diffstat (limited to 'fs/splice.c')
-rw-r--r-- | fs/splice.c | 33 |
1 files changed, 13 insertions, 20 deletions
diff --git a/fs/splice.c b/fs/splice.c index e30743c2c06a..36bc262dfbd5 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -150,8 +150,6 @@ static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages, | |||
150 | mutex_lock(&pipe->inode->i_mutex); | 150 | mutex_lock(&pipe->inode->i_mutex); |
151 | 151 | ||
152 | for (;;) { | 152 | for (;;) { |
153 | int bufs; | ||
154 | |||
155 | if (!pipe->readers) { | 153 | if (!pipe->readers) { |
156 | send_sig(SIGPIPE, current, 0); | 154 | send_sig(SIGPIPE, current, 0); |
157 | if (!ret) | 155 | if (!ret) |
@@ -159,9 +157,8 @@ static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages, | |||
159 | break; | 157 | break; |
160 | } | 158 | } |
161 | 159 | ||
162 | bufs = pipe->nrbufs; | 160 | if (pipe->nrbufs < PIPE_BUFFERS) { |
163 | if (bufs < PIPE_BUFFERS) { | 161 | int newbuf = (pipe->curbuf + pipe->nrbufs) & (PIPE_BUFFERS - 1); |
164 | int newbuf = (pipe->curbuf + bufs) & (PIPE_BUFFERS - 1); | ||
165 | struct pipe_buffer *buf = pipe->bufs + newbuf; | 162 | struct pipe_buffer *buf = pipe->bufs + newbuf; |
166 | struct page *page = pages[i++]; | 163 | struct page *page = pages[i++]; |
167 | unsigned long this_len; | 164 | unsigned long this_len; |
@@ -174,8 +171,9 @@ static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages, | |||
174 | buf->offset = offset; | 171 | buf->offset = offset; |
175 | buf->len = this_len; | 172 | buf->len = this_len; |
176 | buf->ops = &page_cache_pipe_buf_ops; | 173 | buf->ops = &page_cache_pipe_buf_ops; |
177 | pipe->nrbufs = ++bufs; | 174 | pipe->nrbufs++; |
178 | do_wakeup = 1; | 175 | if (pipe->inode) |
176 | do_wakeup = 1; | ||
179 | 177 | ||
180 | ret += this_len; | 178 | ret += this_len; |
181 | len -= this_len; | 179 | len -= this_len; |
@@ -184,7 +182,7 @@ static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages, | |||
184 | break; | 182 | break; |
185 | if (!len) | 183 | if (!len) |
186 | break; | 184 | break; |
187 | if (bufs < PIPE_BUFFERS) | 185 | if (pipe->nrbufs < PIPE_BUFFERS) |
188 | continue; | 186 | continue; |
189 | 187 | ||
190 | break; | 188 | break; |
@@ -581,11 +579,8 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, | |||
581 | mutex_lock(&pipe->inode->i_mutex); | 579 | mutex_lock(&pipe->inode->i_mutex); |
582 | 580 | ||
583 | for (;;) { | 581 | for (;;) { |
584 | int bufs = pipe->nrbufs; | 582 | if (pipe->nrbufs) { |
585 | 583 | struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; | |
586 | if (bufs) { | ||
587 | int curbuf = pipe->curbuf; | ||
588 | struct pipe_buffer *buf = pipe->bufs + curbuf; | ||
589 | struct pipe_buf_operations *ops = buf->ops; | 584 | struct pipe_buf_operations *ops = buf->ops; |
590 | 585 | ||
591 | sd.len = buf->len; | 586 | sd.len = buf->len; |
@@ -606,10 +601,10 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, | |||
606 | if (!buf->len) { | 601 | if (!buf->len) { |
607 | buf->ops = NULL; | 602 | buf->ops = NULL; |
608 | ops->release(pipe, buf); | 603 | ops->release(pipe, buf); |
609 | curbuf = (curbuf + 1) & (PIPE_BUFFERS - 1); | 604 | pipe->curbuf = (pipe->curbuf + 1) & (PIPE_BUFFERS - 1); |
610 | pipe->curbuf = curbuf; | 605 | pipe->nrbufs--; |
611 | pipe->nrbufs = --bufs; | 606 | if (pipe->inode) |
612 | do_wakeup = 1; | 607 | do_wakeup = 1; |
613 | } | 608 | } |
614 | 609 | ||
615 | sd.pos += sd.len; | 610 | sd.pos += sd.len; |
@@ -618,7 +613,7 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, | |||
618 | break; | 613 | break; |
619 | } | 614 | } |
620 | 615 | ||
621 | if (bufs) | 616 | if (pipe->nrbufs) |
622 | continue; | 617 | continue; |
623 | if (!pipe->writers) | 618 | if (!pipe->writers) |
624 | break; | 619 | break; |
@@ -660,9 +655,7 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, | |||
660 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | 655 | kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); |
661 | } | 656 | } |
662 | 657 | ||
663 | mutex_lock(&out->f_mapping->host->i_mutex); | ||
664 | out->f_pos = sd.pos; | 658 | out->f_pos = sd.pos; |
665 | mutex_unlock(&out->f_mapping->host->i_mutex); | ||
666 | return ret; | 659 | return ret; |
667 | 660 | ||
668 | } | 661 | } |