aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/splice.c217
-rw-r--r--include/linux/splice.h10
2 files changed, 153 insertions, 74 deletions
diff --git a/fs/splice.c b/fs/splice.c
index c18aa7e03e2b..fd6b278d447b 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -601,107 +601,176 @@ out:
601 return ret; 601 return ret;
602} 602}
603 603
604static void wakeup_pipe_writers(struct pipe_inode_info *pipe)
605{
606 smp_mb();
607 if (waitqueue_active(&pipe->wait))
608 wake_up_interruptible(&pipe->wait);
609 kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
610}
611
604/** 612/**
605 * __splice_from_pipe - splice data from a pipe to given actor 613 * splice_from_pipe_feed - feed available data from a pipe to a file
606 * @pipe: pipe to splice from 614 * @pipe: pipe to splice from
607 * @sd: information to @actor 615 * @sd: information to @actor
608 * @actor: handler that splices the data 616 * @actor: handler that splices the data
609 * 617 *
610 * Description: 618 * Description:
611 * This function does little more than loop over the pipe and call 619
612 * @actor to do the actual moving of a single struct pipe_buffer to 620 * This function loops over the pipe and calls @actor to do the
613 * the desired destination. See pipe_to_file, pipe_to_sendpage, or 621 * actual moving of a single struct pipe_buffer to the desired
614 * pipe_to_user. 622 * destination. It returns when there's no more buffers left in
623 * the pipe or if the requested number of bytes (@sd->total_len)
624 * have been copied. It returns a positive number (one) if the
625 * pipe needs to be filled with more data, zero if the required
626 * number of bytes have been copied and -errno on error.
615 * 627 *
628 * This, together with splice_from_pipe_{begin,end,next}, may be
629 * used to implement the functionality of __splice_from_pipe() when
630 * locking is required around copying the pipe buffers to the
631 * destination.
616 */ 632 */
617ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd, 633int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd,
618 splice_actor *actor) 634 splice_actor *actor)
619{ 635{
620 int ret, do_wakeup, err; 636 int ret;
621
622 ret = 0;
623 do_wakeup = 0;
624
625 for (;;) {
626 if (pipe->nrbufs) {
627 struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
628 const struct pipe_buf_operations *ops = buf->ops;
629 637
630 sd->len = buf->len; 638 while (pipe->nrbufs) {
631 if (sd->len > sd->total_len) 639 struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
632 sd->len = sd->total_len; 640 const struct pipe_buf_operations *ops = buf->ops;
633 641
634 err = actor(pipe, buf, sd); 642 sd->len = buf->len;
635 if (err <= 0) { 643 if (sd->len > sd->total_len)
636 if (!ret && err != -ENODATA) 644 sd->len = sd->total_len;
637 ret = err;
638 645
639 break; 646 ret = actor(pipe, buf, sd);
640 } 647 if (ret <= 0) {
648 if (ret == -ENODATA)
649 ret = 0;
650 return ret;
651 }
652 buf->offset += ret;
653 buf->len -= ret;
641 654
642 ret += err; 655 sd->num_spliced += ret;
643 buf->offset += err; 656 sd->len -= ret;
644 buf->len -= err; 657 sd->pos += ret;
658 sd->total_len -= ret;
645 659
646 sd->len -= err; 660 if (!buf->len) {
647 sd->pos += err; 661 buf->ops = NULL;
648 sd->total_len -= err; 662 ops->release(pipe, buf);
649 if (sd->len) 663 pipe->curbuf = (pipe->curbuf + 1) & (PIPE_BUFFERS - 1);
650 continue; 664 pipe->nrbufs--;
665 if (pipe->inode)
666 sd->need_wakeup = true;
667 }
651 668
652 if (!buf->len) { 669 if (!sd->total_len)
653 buf->ops = NULL; 670 return 0;
654 ops->release(pipe, buf); 671 }
655 pipe->curbuf = (pipe->curbuf + 1) & (PIPE_BUFFERS - 1);
656 pipe->nrbufs--;
657 if (pipe->inode)
658 do_wakeup = 1;
659 }
660 672
661 if (!sd->total_len) 673 return 1;
662 break; 674}
663 } 675EXPORT_SYMBOL(splice_from_pipe_feed);
664 676
665 if (pipe->nrbufs) 677/**
666 continue; 678 * splice_from_pipe_next - wait for some data to splice from
679 * @pipe: pipe to splice from
680 * @sd: information about the splice operation
681 *
682 * Description:
683 * This function will wait for some data and return a positive
684 * value (one) if pipe buffers are available. It will return zero
685 * or -errno if no more data needs to be spliced.
686 */
687int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd)
688{
689 while (!pipe->nrbufs) {
667 if (!pipe->writers) 690 if (!pipe->writers)
668 break; 691 return 0;
669 if (!pipe->waiting_writers) {
670 if (ret)
671 break;
672 }
673 692
674 if (sd->flags & SPLICE_F_NONBLOCK) { 693 if (!pipe->waiting_writers && sd->num_spliced)
675 if (!ret) 694 return 0;
676 ret = -EAGAIN;
677 break;
678 }
679 695
680 if (signal_pending(current)) { 696 if (sd->flags & SPLICE_F_NONBLOCK)
681 if (!ret) 697 return -EAGAIN;
682 ret = -ERESTARTSYS;
683 break;
684 }
685 698
686 if (do_wakeup) { 699 if (signal_pending(current))
687 smp_mb(); 700 return -ERESTARTSYS;
688 if (waitqueue_active(&pipe->wait)) 701
689 wake_up_interruptible_sync(&pipe->wait); 702 if (sd->need_wakeup) {
690 kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); 703 wakeup_pipe_writers(pipe);
691 do_wakeup = 0; 704 sd->need_wakeup = false;
692 } 705 }
693 706
694 pipe_wait(pipe); 707 pipe_wait(pipe);
695 } 708 }
696 709
697 if (do_wakeup) { 710 return 1;
698 smp_mb(); 711}
699 if (waitqueue_active(&pipe->wait)) 712EXPORT_SYMBOL(splice_from_pipe_next);
700 wake_up_interruptible(&pipe->wait);
701 kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
702 }
703 713
704 return ret; 714/**
715 * splice_from_pipe_begin - start splicing from pipe
716 * @pipe: pipe to splice from
717 *
718 * Description:
719 * This function should be called before a loop containing
720 * splice_from_pipe_next() and splice_from_pipe_feed() to
721 * initialize the necessary fields of @sd.
722 */
723void splice_from_pipe_begin(struct splice_desc *sd)
724{
725 sd->num_spliced = 0;
726 sd->need_wakeup = false;
727}
728EXPORT_SYMBOL(splice_from_pipe_begin);
729
730/**
731 * splice_from_pipe_end - finish splicing from pipe
732 * @pipe: pipe to splice from
733 * @sd: information about the splice operation
734 *
735 * Description:
736 * This function will wake up pipe writers if necessary. It should
737 * be called after a loop containing splice_from_pipe_next() and
738 * splice_from_pipe_feed().
739 */
740void splice_from_pipe_end(struct pipe_inode_info *pipe, struct splice_desc *sd)
741{
742 if (sd->need_wakeup)
743 wakeup_pipe_writers(pipe);
744}
745EXPORT_SYMBOL(splice_from_pipe_end);
746
747/**
748 * __splice_from_pipe - splice data from a pipe to given actor
749 * @pipe: pipe to splice from
750 * @sd: information to @actor
751 * @actor: handler that splices the data
752 *
753 * Description:
754 * This function does little more than loop over the pipe and call
755 * @actor to do the actual moving of a single struct pipe_buffer to
756 * the desired destination. See pipe_to_file, pipe_to_sendpage, or
757 * pipe_to_user.
758 *
759 */
760ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
761 splice_actor *actor)
762{
763 int ret;
764
765 splice_from_pipe_begin(sd);
766 do {
767 ret = splice_from_pipe_next(pipe, sd);
768 if (ret > 0)
769 ret = splice_from_pipe_feed(pipe, sd, actor);
770 } while (ret > 0);
771 splice_from_pipe_end(pipe, sd);
772
773 return sd->num_spliced ? sd->num_spliced : ret;
705} 774}
706EXPORT_SYMBOL(__splice_from_pipe); 775EXPORT_SYMBOL(__splice_from_pipe);
707 776
diff --git a/include/linux/splice.h b/include/linux/splice.h
index 528dcb93c2f2..8fc2a635586e 100644
--- a/include/linux/splice.h
+++ b/include/linux/splice.h
@@ -36,6 +36,8 @@ struct splice_desc {
36 void *data; /* cookie */ 36 void *data; /* cookie */
37 } u; 37 } u;
38 loff_t pos; /* file position */ 38 loff_t pos; /* file position */
39 size_t num_spliced; /* number of bytes already spliced */
40 bool need_wakeup; /* need to wake up writer */
39}; 41};
40 42
41struct partial_page { 43struct partial_page {
@@ -66,6 +68,14 @@ extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
66 splice_actor *); 68 splice_actor *);
67extern ssize_t __splice_from_pipe(struct pipe_inode_info *, 69extern ssize_t __splice_from_pipe(struct pipe_inode_info *,
68 struct splice_desc *, splice_actor *); 70 struct splice_desc *, splice_actor *);
71extern int splice_from_pipe_feed(struct pipe_inode_info *, struct splice_desc *,
72 splice_actor *);
73extern int splice_from_pipe_next(struct pipe_inode_info *,
74 struct splice_desc *);
75extern void splice_from_pipe_begin(struct splice_desc *);
76extern void splice_from_pipe_end(struct pipe_inode_info *,
77 struct splice_desc *);
78
69extern ssize_t splice_to_pipe(struct pipe_inode_info *, 79extern ssize_t splice_to_pipe(struct pipe_inode_info *,
70 struct splice_pipe_desc *); 80 struct splice_pipe_desc *);
71extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, 81extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,