aboutsummaryrefslogtreecommitdiffstats
path: root/fs/splice.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/splice.c')
-rw-r--r--fs/splice.c122
1 files changed, 63 insertions, 59 deletions
diff --git a/fs/splice.c b/fs/splice.c
index 9bfd6af0cf45..ed91a62402e0 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -136,34 +136,33 @@ static struct pipe_buf_operations page_cache_pipe_buf_ops = {
136 * Pipe output worker. This sets up our pipe format with the page cache 136 * Pipe output worker. This sets up our pipe format with the page cache
137 * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). 137 * pipe buffer operations. Otherwise very similar to the regular pipe_writev().
138 */ 138 */
139static ssize_t move_to_pipe(struct inode *inode, struct page **pages, 139static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages,
140 int nr_pages, unsigned long offset, 140 int nr_pages, unsigned long offset,
141 unsigned long len, unsigned int flags) 141 unsigned long len, unsigned int flags)
142{ 142{
143 struct pipe_inode_info *info;
144 int ret, do_wakeup, i; 143 int ret, do_wakeup, i;
145 144
146 ret = 0; 145 ret = 0;
147 do_wakeup = 0; 146 do_wakeup = 0;
148 i = 0; 147 i = 0;
149 148
150 mutex_lock(PIPE_MUTEX(*inode)); 149 if (pipe->inode)
150 mutex_lock(&pipe->inode->i_mutex);
151 151
152 info = inode->i_pipe;
153 for (;;) { 152 for (;;) {
154 int bufs; 153 int bufs;
155 154
156 if (!PIPE_READERS(*inode)) { 155 if (!pipe->readers) {
157 send_sig(SIGPIPE, current, 0); 156 send_sig(SIGPIPE, current, 0);
158 if (!ret) 157 if (!ret)
159 ret = -EPIPE; 158 ret = -EPIPE;
160 break; 159 break;
161 } 160 }
162 161
163 bufs = info->nrbufs; 162 bufs = pipe->nrbufs;
164 if (bufs < PIPE_BUFFERS) { 163 if (bufs < PIPE_BUFFERS) {
165 int newbuf = (info->curbuf + bufs) & (PIPE_BUFFERS - 1); 164 int newbuf = (pipe->curbuf + bufs) & (PIPE_BUFFERS - 1);
166 struct pipe_buffer *buf = info->bufs + newbuf; 165 struct pipe_buffer *buf = pipe->bufs + newbuf;
167 struct page *page = pages[i++]; 166 struct page *page = pages[i++];
168 unsigned long this_len; 167 unsigned long this_len;
169 168
@@ -175,7 +174,7 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
175 buf->offset = offset; 174 buf->offset = offset;
176 buf->len = this_len; 175 buf->len = this_len;
177 buf->ops = &page_cache_pipe_buf_ops; 176 buf->ops = &page_cache_pipe_buf_ops;
178 info->nrbufs = ++bufs; 177 pipe->nrbufs = ++bufs;
179 do_wakeup = 1; 178 do_wakeup = 1;
180 179
181 ret += this_len; 180 ret += this_len;
@@ -205,25 +204,25 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
205 204
206 if (do_wakeup) { 205 if (do_wakeup) {
207 smp_mb(); 206 smp_mb();
208 if (waitqueue_active(PIPE_WAIT(*inode))) 207 if (waitqueue_active(&pipe->wait))
209 wake_up_interruptible_sync(PIPE_WAIT(*inode)); 208 wake_up_interruptible_sync(&pipe->wait);
210 kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, 209 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
211 POLL_IN);
212 do_wakeup = 0; 210 do_wakeup = 0;
213 } 211 }
214 212
215 PIPE_WAITING_WRITERS(*inode)++; 213 pipe->waiting_writers++;
216 pipe_wait(inode); 214 pipe_wait(pipe);
217 PIPE_WAITING_WRITERS(*inode)--; 215 pipe->waiting_writers--;
218 } 216 }
219 217
220 mutex_unlock(PIPE_MUTEX(*inode)); 218 if (pipe->inode)
219 mutex_unlock(&pipe->inode->i_mutex);
221 220
222 if (do_wakeup) { 221 if (do_wakeup) {
223 smp_mb(); 222 smp_mb();
224 if (waitqueue_active(PIPE_WAIT(*inode))) 223 if (waitqueue_active(&pipe->wait))
225 wake_up_interruptible(PIPE_WAIT(*inode)); 224 wake_up_interruptible(&pipe->wait);
226 kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN); 225 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
227 } 226 }
228 227
229 while (i < nr_pages) 228 while (i < nr_pages)
@@ -232,8 +231,9 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
232 return ret; 231 return ret;
233} 232}
234 233
235static int __generic_file_splice_read(struct file *in, struct inode *pipe, 234static int
236 size_t len, unsigned int flags) 235__generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe,
236 size_t len, unsigned int flags)
237{ 237{
238 struct address_space *mapping = in->f_mapping; 238 struct address_space *mapping = in->f_mapping;
239 unsigned int offset, nr_pages; 239 unsigned int offset, nr_pages;
@@ -298,7 +298,7 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe,
298 * Will read pages from given file and fill them into a pipe. 298 * Will read pages from given file and fill them into a pipe.
299 * 299 *
300 */ 300 */
301ssize_t generic_file_splice_read(struct file *in, struct inode *pipe, 301ssize_t generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe,
302 size_t len, unsigned int flags) 302 size_t len, unsigned int flags)
303{ 303{
304 ssize_t spliced; 304 ssize_t spliced;
@@ -306,6 +306,7 @@ ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
306 306
307 ret = 0; 307 ret = 0;
308 spliced = 0; 308 spliced = 0;
309
309 while (len) { 310 while (len) {
310 ret = __generic_file_splice_read(in, pipe, len, flags); 311 ret = __generic_file_splice_read(in, pipe, len, flags);
311 312
@@ -509,11 +510,10 @@ typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
509 * key here is the 'actor' worker passed in that actually moves the data 510 * key here is the 'actor' worker passed in that actually moves the data
510 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. 511 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
511 */ 512 */
512static ssize_t move_from_pipe(struct inode *inode, struct file *out, 513static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out,
513 size_t len, unsigned int flags, 514 size_t len, unsigned int flags,
514 splice_actor *actor) 515 splice_actor *actor)
515{ 516{
516 struct pipe_inode_info *info;
517 int ret, do_wakeup, err; 517 int ret, do_wakeup, err;
518 struct splice_desc sd; 518 struct splice_desc sd;
519 519
@@ -525,22 +525,22 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
525 sd.file = out; 525 sd.file = out;
526 sd.pos = out->f_pos; 526 sd.pos = out->f_pos;
527 527
528 mutex_lock(PIPE_MUTEX(*inode)); 528 if (pipe->inode)
529 mutex_lock(&pipe->inode->i_mutex);
529 530
530 info = inode->i_pipe;
531 for (;;) { 531 for (;;) {
532 int bufs = info->nrbufs; 532 int bufs = pipe->nrbufs;
533 533
534 if (bufs) { 534 if (bufs) {
535 int curbuf = info->curbuf; 535 int curbuf = pipe->curbuf;
536 struct pipe_buffer *buf = info->bufs + curbuf; 536 struct pipe_buffer *buf = pipe->bufs + curbuf;
537 struct pipe_buf_operations *ops = buf->ops; 537 struct pipe_buf_operations *ops = buf->ops;
538 538
539 sd.len = buf->len; 539 sd.len = buf->len;
540 if (sd.len > sd.total_len) 540 if (sd.len > sd.total_len)
541 sd.len = sd.total_len; 541 sd.len = sd.total_len;
542 542
543 err = actor(info, buf, &sd); 543 err = actor(pipe, buf, &sd);
544 if (err) { 544 if (err) {
545 if (!ret && err != -ENODATA) 545 if (!ret && err != -ENODATA)
546 ret = err; 546 ret = err;
@@ -553,10 +553,10 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
553 buf->len -= sd.len; 553 buf->len -= sd.len;
554 if (!buf->len) { 554 if (!buf->len) {
555 buf->ops = NULL; 555 buf->ops = NULL;
556 ops->release(info, buf); 556 ops->release(pipe, buf);
557 curbuf = (curbuf + 1) & (PIPE_BUFFERS - 1); 557 curbuf = (curbuf + 1) & (PIPE_BUFFERS - 1);
558 info->curbuf = curbuf; 558 pipe->curbuf = curbuf;
559 info->nrbufs = --bufs; 559 pipe->nrbufs = --bufs;
560 do_wakeup = 1; 560 do_wakeup = 1;
561 } 561 }
562 562
@@ -568,9 +568,9 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
568 568
569 if (bufs) 569 if (bufs)
570 continue; 570 continue;
571 if (!PIPE_WRITERS(*inode)) 571 if (!pipe->writers)
572 break; 572 break;
573 if (!PIPE_WAITING_WRITERS(*inode)) { 573 if (!pipe->waiting_writers) {
574 if (ret) 574 if (ret)
575 break; 575 break;
576 } 576 }
@@ -589,22 +589,23 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
589 589
590 if (do_wakeup) { 590 if (do_wakeup) {
591 smp_mb(); 591 smp_mb();
592 if (waitqueue_active(PIPE_WAIT(*inode))) 592 if (waitqueue_active(&pipe->wait))
593 wake_up_interruptible_sync(PIPE_WAIT(*inode)); 593 wake_up_interruptible_sync(&pipe->wait);
594 kill_fasync(PIPE_FASYNC_WRITERS(*inode),SIGIO,POLL_OUT); 594 kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
595 do_wakeup = 0; 595 do_wakeup = 0;
596 } 596 }
597 597
598 pipe_wait(inode); 598 pipe_wait(pipe);
599 } 599 }
600 600
601 mutex_unlock(PIPE_MUTEX(*inode)); 601 if (pipe->inode)
602 mutex_unlock(&pipe->inode->i_mutex);
602 603
603 if (do_wakeup) { 604 if (do_wakeup) {
604 smp_mb(); 605 smp_mb();
605 if (waitqueue_active(PIPE_WAIT(*inode))) 606 if (waitqueue_active(&pipe->wait))
606 wake_up_interruptible(PIPE_WAIT(*inode)); 607 wake_up_interruptible(&pipe->wait);
607 kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT); 608 kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
608 } 609 }
609 610
610 mutex_lock(&out->f_mapping->host->i_mutex); 611 mutex_lock(&out->f_mapping->host->i_mutex);
@@ -616,7 +617,7 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
616 617
617/** 618/**
618 * generic_file_splice_write - splice data from a pipe to a file 619 * generic_file_splice_write - splice data from a pipe to a file
619 * @inode: pipe inode 620 * @pipe: pipe info
620 * @out: file to write to 621 * @out: file to write to
621 * @len: number of bytes to splice 622 * @len: number of bytes to splice
622 * @flags: splice modifier flags 623 * @flags: splice modifier flags
@@ -625,11 +626,14 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
625 * the given pipe inode to the given file. 626 * the given pipe inode to the given file.
626 * 627 *
627 */ 628 */
628ssize_t generic_file_splice_write(struct inode *inode, struct file *out, 629ssize_t
629 size_t len, unsigned int flags) 630generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
631 size_t len, unsigned int flags)
630{ 632{
631 struct address_space *mapping = out->f_mapping; 633 struct address_space *mapping = out->f_mapping;
632 ssize_t ret = move_from_pipe(inode, out, len, flags, pipe_to_file); 634 ssize_t ret;
635
636 ret = move_from_pipe(pipe, out, len, flags, pipe_to_file);
633 637
634 /* 638 /*
635 * if file or inode is SYNC and we actually wrote some data, sync it 639 * if file or inode is SYNC and we actually wrote some data, sync it
@@ -664,10 +668,10 @@ EXPORT_SYMBOL(generic_file_splice_write);
664 * is involved. 668 * is involved.
665 * 669 *
666 */ 670 */
667ssize_t generic_splice_sendpage(struct inode *inode, struct file *out, 671ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out,
668 size_t len, unsigned int flags) 672 size_t len, unsigned int flags)
669{ 673{
670 return move_from_pipe(inode, out, len, flags, pipe_to_sendpage); 674 return move_from_pipe(pipe, out, len, flags, pipe_to_sendpage);
671} 675}
672 676
673EXPORT_SYMBOL(generic_splice_sendpage); 677EXPORT_SYMBOL(generic_splice_sendpage);
@@ -675,8 +679,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
675/* 679/*
676 * Attempt to initiate a splice from pipe to file. 680 * Attempt to initiate a splice from pipe to file.
677 */ 681 */
678static long do_splice_from(struct inode *pipe, struct file *out, size_t len, 682static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
679 unsigned int flags) 683 size_t len, unsigned int flags)
680{ 684{
681 loff_t pos; 685 loff_t pos;
682 int ret; 686 int ret;
@@ -698,8 +702,8 @@ static long do_splice_from(struct inode *pipe, struct file *out, size_t len,
698/* 702/*
699 * Attempt to initiate a splice from a file to a pipe. 703 * Attempt to initiate a splice from a file to a pipe.
700 */ 704 */
701static long do_splice_to(struct file *in, struct inode *pipe, size_t len, 705static long do_splice_to(struct file *in, struct pipe_inode_info *pipe,
702 unsigned int flags) 706 size_t len, unsigned int flags)
703{ 707{
704 loff_t pos, isize, left; 708 loff_t pos, isize, left;
705 int ret; 709 int ret;
@@ -732,14 +736,14 @@ static long do_splice_to(struct file *in, struct inode *pipe, size_t len,
732static long do_splice(struct file *in, struct file *out, size_t len, 736static long do_splice(struct file *in, struct file *out, size_t len,
733 unsigned int flags) 737 unsigned int flags)
734{ 738{
735 struct inode *pipe; 739 struct pipe_inode_info *pipe;
736 740
737 pipe = in->f_dentry->d_inode; 741 pipe = in->f_dentry->d_inode->i_pipe;
738 if (pipe->i_pipe) 742 if (pipe)
739 return do_splice_from(pipe, out, len, flags); 743 return do_splice_from(pipe, out, len, flags);
740 744
741 pipe = out->f_dentry->d_inode; 745 pipe = out->f_dentry->d_inode->i_pipe;
742 if (pipe->i_pipe) 746 if (pipe)
743 return do_splice_to(in, pipe, len, flags); 747 return do_splice_to(in, pipe, len, flags);
744 748
745 return -EINVAL; 749 return -EINVAL;