aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/splice.c33
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}