aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2007-06-12 15:17:17 -0400
committerJens Axboe <jens.axboe@oracle.com>2007-07-10 02:04:12 -0400
commitc66ab6fa705e1b2887a6d9246b798bdc526839e2 (patch)
tree764ece0ee44f937012dfaa1657709da548ed5b16
parent71780f59e127bb281a9302d430495ca9586c14e7 (diff)
splice: abstract out actor data
For direct splicing (or private splicing), the output may not be a file. So abstract out the handling into a specified actor function and put the data in the splice_desc structure earlier, so we can build on top of that. This is the first step in better splice handling for drivers, and also for implementing vmsplice _to_ user memory. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--fs/ocfs2/file.c11
-rw-r--r--fs/splice.c99
-rw-r--r--include/linux/pipe_fs_i.h10
3 files changed, 84 insertions, 36 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index ac6c96431bbc..93565c03d315 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1636,9 +1636,14 @@ static ssize_t __ocfs2_file_splice_write(struct pipe_inode_info *pipe,
1636 int ret, err; 1636 int ret, err;
1637 struct address_space *mapping = out->f_mapping; 1637 struct address_space *mapping = out->f_mapping;
1638 struct inode *inode = mapping->host; 1638 struct inode *inode = mapping->host;
1639 1639 struct splice_desc sd = {
1640 ret = __splice_from_pipe(pipe, out, ppos, len, flags, 1640 .total_len = len,
1641 ocfs2_splice_write_actor); 1641 .flags = flags,
1642 .pos = *ppos,
1643 .file = out,
1644 };
1645
1646 ret = __splice_from_pipe(pipe, &sd, ocfs2_splice_write_actor);
1642 if (ret > 0) { 1647 if (ret > 0) {
1643 *ppos += ret; 1648 *ppos += ret;
1644 1649
diff --git a/fs/splice.c b/fs/splice.c
index e7d7080de2f9..68f6328236a6 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -668,31 +668,24 @@ out_ret:
668 * key here is the 'actor' worker passed in that actually moves the data 668 * key here is the 'actor' worker passed in that actually moves the data
669 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. 669 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
670 */ 670 */
671ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, 671ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
672 struct file *out, loff_t *ppos, size_t len, 672 splice_actor *actor)
673 unsigned int flags, splice_actor *actor)
674{ 673{
675 int ret, do_wakeup, err; 674 int ret, do_wakeup, err;
676 struct splice_desc sd;
677 675
678 ret = 0; 676 ret = 0;
679 do_wakeup = 0; 677 do_wakeup = 0;
680 678
681 sd.total_len = len;
682 sd.flags = flags;
683 sd.file = out;
684 sd.pos = *ppos;
685
686 for (;;) { 679 for (;;) {
687 if (pipe->nrbufs) { 680 if (pipe->nrbufs) {
688 struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; 681 struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
689 const struct pipe_buf_operations *ops = buf->ops; 682 const struct pipe_buf_operations *ops = buf->ops;
690 683
691 sd.len = buf->len; 684 sd->len = buf->len;
692 if (sd.len > sd.total_len) 685 if (sd->len > sd->total_len)
693 sd.len = sd.total_len; 686 sd->len = sd->total_len;
694 687
695 err = actor(pipe, buf, &sd); 688 err = actor(pipe, buf, sd);
696 if (err <= 0) { 689 if (err <= 0) {
697 if (!ret && err != -ENODATA) 690 if (!ret && err != -ENODATA)
698 ret = err; 691 ret = err;
@@ -704,10 +697,10 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
704 buf->offset += err; 697 buf->offset += err;
705 buf->len -= err; 698 buf->len -= err;
706 699
707 sd.len -= err; 700 sd->len -= err;
708 sd.pos += err; 701 sd->pos += err;
709 sd.total_len -= err; 702 sd->total_len -= err;
710 if (sd.len) 703 if (sd->len)
711 continue; 704 continue;
712 705
713 if (!buf->len) { 706 if (!buf->len) {
@@ -719,7 +712,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
719 do_wakeup = 1; 712 do_wakeup = 1;
720 } 713 }
721 714
722 if (!sd.total_len) 715 if (!sd->total_len)
723 break; 716 break;
724 } 717 }
725 718
@@ -732,7 +725,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
732 break; 725 break;
733 } 726 }
734 727
735 if (flags & SPLICE_F_NONBLOCK) { 728 if (sd->flags & SPLICE_F_NONBLOCK) {
736 if (!ret) 729 if (!ret)
737 ret = -EAGAIN; 730 ret = -EAGAIN;
738 break; 731 break;
@@ -772,6 +765,12 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
772{ 765{
773 ssize_t ret; 766 ssize_t ret;
774 struct inode *inode = out->f_mapping->host; 767 struct inode *inode = out->f_mapping->host;
768 struct splice_desc sd = {
769 .total_len = len,
770 .flags = flags,
771 .pos = *ppos,
772 .file = out,
773 };
775 774
776 /* 775 /*
777 * The actor worker might be calling ->prepare_write and 776 * The actor worker might be calling ->prepare_write and
@@ -780,7 +779,7 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
780 * pipe->inode, we have to order lock acquiry here. 779 * pipe->inode, we have to order lock acquiry here.
781 */ 780 */
782 inode_double_lock(inode, pipe->inode); 781 inode_double_lock(inode, pipe->inode);
783 ret = __splice_from_pipe(pipe, out, ppos, len, flags, actor); 782 ret = __splice_from_pipe(pipe, &sd, actor);
784 inode_double_unlock(inode, pipe->inode); 783 inode_double_unlock(inode, pipe->inode);
785 784
786 return ret; 785 return ret;
@@ -804,6 +803,12 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
804{ 803{
805 struct address_space *mapping = out->f_mapping; 804 struct address_space *mapping = out->f_mapping;
806 struct inode *inode = mapping->host; 805 struct inode *inode = mapping->host;
806 struct splice_desc sd = {
807 .total_len = len,
808 .flags = flags,
809 .pos = *ppos,
810 .file = out,
811 };
807 ssize_t ret; 812 ssize_t ret;
808 int err; 813 int err;
809 814
@@ -811,7 +816,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
811 if (unlikely(err)) 816 if (unlikely(err))
812 return err; 817 return err;
813 818
814 ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); 819 ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
815 if (ret > 0) { 820 if (ret > 0) {
816 unsigned long nr_pages; 821 unsigned long nr_pages;
817 822
@@ -956,14 +961,17 @@ static long do_splice_to(struct file *in, loff_t *ppos,
956 return in->f_op->splice_read(in, ppos, pipe, len, flags); 961 return in->f_op->splice_read(in, ppos, pipe, len, flags);
957} 962}
958 963
959long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, 964/*
960 size_t len, unsigned int flags) 965 * Splices from an input file to an actor, using a 'direct' pipe.
966 */
967ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
968 splice_direct_actor *actor)
961{ 969{
962 struct pipe_inode_info *pipe; 970 struct pipe_inode_info *pipe;
963 long ret, bytes; 971 long ret, bytes;
964 loff_t out_off;
965 umode_t i_mode; 972 umode_t i_mode;
966 int i; 973 size_t len;
974 int i, flags;
967 975
968 /* 976 /*
969 * We require the input being a regular file, as we don't want to 977 * We require the input being a regular file, as we don't want to
@@ -999,7 +1007,13 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
999 */ 1007 */
1000 ret = 0; 1008 ret = 0;
1001 bytes = 0; 1009 bytes = 0;
1002 out_off = 0; 1010 len = sd->total_len;
1011 flags = sd->flags;
1012
1013 /*
1014 * Don't block on output, we have to drain the direct pipe.
1015 */
1016 sd->flags &= ~SPLICE_F_NONBLOCK;
1003 1017
1004 while (len) { 1018 while (len) {
1005 size_t read_len, max_read_len; 1019 size_t read_len, max_read_len;
@@ -1009,19 +1023,19 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
1009 */ 1023 */
1010 max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE)); 1024 max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE));
1011 1025
1012 ret = do_splice_to(in, ppos, pipe, max_read_len, flags); 1026 ret = do_splice_to(in, &sd->pos, pipe, max_read_len, flags);
1013 if (unlikely(ret < 0)) 1027 if (unlikely(ret < 0))
1014 goto out_release; 1028 goto out_release;
1015 1029
1016 read_len = ret; 1030 read_len = ret;
1031 sd->total_len = read_len;
1017 1032
1018 /* 1033 /*
1019 * NOTE: nonblocking mode only applies to the input. We 1034 * NOTE: nonblocking mode only applies to the input. We
1020 * must not do the output in nonblocking mode as then we 1035 * must not do the output in nonblocking mode as then we
1021 * could get stuck data in the internal pipe: 1036 * could get stuck data in the internal pipe:
1022 */ 1037 */
1023 ret = do_splice_from(pipe, out, &out_off, read_len, 1038 ret = actor(pipe, sd);
1024 flags & ~SPLICE_F_NONBLOCK);
1025 if (unlikely(ret < 0)) 1039 if (unlikely(ret < 0))
1026 goto out_release; 1040 goto out_release;
1027 1041
@@ -1066,6 +1080,33 @@ out_release:
1066 return bytes; 1080 return bytes;
1067 1081
1068 return ret; 1082 return ret;
1083
1084}
1085EXPORT_SYMBOL(splice_direct_to_actor);
1086
1087static int direct_splice_actor(struct pipe_inode_info *pipe,
1088 struct splice_desc *sd)
1089{
1090 struct file *file = sd->file;
1091
1092 return do_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags);
1093}
1094
1095long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
1096 size_t len, unsigned int flags)
1097{
1098 struct splice_desc sd = {
1099 .len = len,
1100 .total_len = len,
1101 .flags = flags,
1102 .pos = *ppos,
1103 .file = out,
1104 };
1105 size_t ret;
1106
1107 ret = splice_direct_to_actor(in, &sd, direct_splice_actor);
1108 *ppos = sd.pos;
1109 return ret;
1069} 1110}
1070 1111
1071/* 1112/*
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index c8884f971228..883ba9b78d3f 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -94,13 +94,15 @@ struct splice_desc {
94 94
95typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, 95typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
96 struct splice_desc *); 96 struct splice_desc *);
97typedef int (splice_direct_actor)(struct pipe_inode_info *,
98 struct splice_desc *);
97 99
98extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *, 100extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
99 loff_t *, size_t, unsigned int, 101 loff_t *, size_t, unsigned int,
100 splice_actor *); 102 splice_actor *);
101 103extern ssize_t __splice_from_pipe(struct pipe_inode_info *,
102extern ssize_t __splice_from_pipe(struct pipe_inode_info *, struct file *, 104 struct splice_desc *, splice_actor *);
103 loff_t *, size_t, unsigned int, 105extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
104 splice_actor *); 106 splice_direct_actor *);
105 107
106#endif 108#endif