aboutsummaryrefslogtreecommitdiffstats
path: root/fs/splice.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/splice.c')
-rw-r--r--fs/splice.c272
1 files changed, 230 insertions, 42 deletions
diff --git a/fs/splice.c b/fs/splice.c
index e50a460239dd..8d57e89924a6 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -125,12 +125,19 @@ static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info,
125 kunmap(buf->page); 125 kunmap(buf->page);
126} 126}
127 127
128static void page_cache_pipe_buf_get(struct pipe_inode_info *info,
129 struct pipe_buffer *buf)
130{
131 page_cache_get(buf->page);
132}
133
128static struct pipe_buf_operations page_cache_pipe_buf_ops = { 134static struct pipe_buf_operations page_cache_pipe_buf_ops = {
129 .can_merge = 0, 135 .can_merge = 0,
130 .map = page_cache_pipe_buf_map, 136 .map = page_cache_pipe_buf_map,
131 .unmap = page_cache_pipe_buf_unmap, 137 .unmap = page_cache_pipe_buf_unmap,
132 .release = page_cache_pipe_buf_release, 138 .release = page_cache_pipe_buf_release,
133 .steal = page_cache_pipe_buf_steal, 139 .steal = page_cache_pipe_buf_steal,
140 .get = page_cache_pipe_buf_get,
134}; 141};
135 142
136/* 143/*
@@ -231,8 +238,9 @@ static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages,
231} 238}
232 239
233static int 240static int
234__generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe, 241__generic_file_splice_read(struct file *in, loff_t *ppos,
235 size_t len, unsigned int flags) 242 struct pipe_inode_info *pipe, size_t len,
243 unsigned int flags)
236{ 244{
237 struct address_space *mapping = in->f_mapping; 245 struct address_space *mapping = in->f_mapping;
238 unsigned int offset, nr_pages; 246 unsigned int offset, nr_pages;
@@ -241,8 +249,8 @@ __generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe,
241 pgoff_t index; 249 pgoff_t index;
242 int i, error; 250 int i, error;
243 251
244 index = in->f_pos >> PAGE_CACHE_SHIFT; 252 index = *ppos >> PAGE_CACHE_SHIFT;
245 offset = in->f_pos & ~PAGE_CACHE_MASK; 253 offset = *ppos & ~PAGE_CACHE_MASK;
246 nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 254 nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
247 255
248 if (nr_pages > PIPE_BUFFERS) 256 if (nr_pages > PIPE_BUFFERS)
@@ -348,8 +356,9 @@ fill_it:
348 * 356 *
349 * Will read pages from given file and fill them into a pipe. 357 * Will read pages from given file and fill them into a pipe.
350 */ 358 */
351ssize_t generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe, 359ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
352 size_t len, unsigned int flags) 360 struct pipe_inode_info *pipe, size_t len,
361 unsigned int flags)
353{ 362{
354 ssize_t spliced; 363 ssize_t spliced;
355 int ret; 364 int ret;
@@ -358,12 +367,12 @@ ssize_t generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe,
358 spliced = 0; 367 spliced = 0;
359 368
360 while (len) { 369 while (len) {
361 ret = __generic_file_splice_read(in, pipe, len, flags); 370 ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
362 371
363 if (ret <= 0) 372 if (ret <= 0)
364 break; 373 break;
365 374
366 in->f_pos += ret; 375 *ppos += ret;
367 len -= ret; 376 len -= ret;
368 spliced += ret; 377 spliced += ret;
369 378
@@ -561,7 +570,7 @@ typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
561 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. 570 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
562 */ 571 */
563static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, 572static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out,
564 size_t len, unsigned int flags, 573 loff_t *ppos, size_t len, unsigned int flags,
565 splice_actor *actor) 574 splice_actor *actor)
566{ 575{
567 int ret, do_wakeup, err; 576 int ret, do_wakeup, err;
@@ -573,7 +582,7 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out,
573 sd.total_len = len; 582 sd.total_len = len;
574 sd.flags = flags; 583 sd.flags = flags;
575 sd.file = out; 584 sd.file = out;
576 sd.pos = out->f_pos; 585 sd.pos = *ppos;
577 586
578 if (pipe->inode) 587 if (pipe->inode)
579 mutex_lock(&pipe->inode->i_mutex); 588 mutex_lock(&pipe->inode->i_mutex);
@@ -656,9 +665,7 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out,
656 kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); 665 kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
657 } 666 }
658 667
659 out->f_pos = sd.pos;
660 return ret; 668 return ret;
661
662} 669}
663 670
664/** 671/**
@@ -674,12 +681,12 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out,
674 */ 681 */
675ssize_t 682ssize_t
676generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, 683generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
677 size_t len, unsigned int flags) 684 loff_t *ppos, size_t len, unsigned int flags)
678{ 685{
679 struct address_space *mapping = out->f_mapping; 686 struct address_space *mapping = out->f_mapping;
680 ssize_t ret; 687 ssize_t ret;
681 688
682 ret = move_from_pipe(pipe, out, len, flags, pipe_to_file); 689 ret = move_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
683 690
684 /* 691 /*
685 * If file or inode is SYNC and we actually wrote some data, sync it. 692 * If file or inode is SYNC and we actually wrote some data, sync it.
@@ -715,9 +722,9 @@ EXPORT_SYMBOL(generic_file_splice_write);
715 * 722 *
716 */ 723 */
717ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, 724ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out,
718 size_t len, unsigned int flags) 725 loff_t *ppos, size_t len, unsigned int flags)
719{ 726{
720 return move_from_pipe(pipe, out, len, flags, pipe_to_sendpage); 727 return move_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage);
721} 728}
722 729
723EXPORT_SYMBOL(generic_splice_sendpage); 730EXPORT_SYMBOL(generic_splice_sendpage);
@@ -726,9 +733,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
726 * Attempt to initiate a splice from pipe to file. 733 * Attempt to initiate a splice from pipe to file.
727 */ 734 */
728static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, 735static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
729 size_t len, unsigned int flags) 736 loff_t *ppos, size_t len, unsigned int flags)
730{ 737{
731 loff_t pos;
732 int ret; 738 int ret;
733 739
734 if (unlikely(!out->f_op || !out->f_op->splice_write)) 740 if (unlikely(!out->f_op || !out->f_op->splice_write))
@@ -737,22 +743,21 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
737 if (unlikely(!(out->f_mode & FMODE_WRITE))) 743 if (unlikely(!(out->f_mode & FMODE_WRITE)))
738 return -EBADF; 744 return -EBADF;
739 745
740 pos = out->f_pos; 746 ret = rw_verify_area(WRITE, out, ppos, len);
741
742 ret = rw_verify_area(WRITE, out, &pos, len);
743 if (unlikely(ret < 0)) 747 if (unlikely(ret < 0))
744 return ret; 748 return ret;
745 749
746 return out->f_op->splice_write(pipe, out, len, flags); 750 return out->f_op->splice_write(pipe, out, ppos, len, flags);
747} 751}
748 752
749/* 753/*
750 * Attempt to initiate a splice from a file to a pipe. 754 * Attempt to initiate a splice from a file to a pipe.
751 */ 755 */
752static long do_splice_to(struct file *in, struct pipe_inode_info *pipe, 756static long do_splice_to(struct file *in, loff_t *ppos,
753 size_t len, unsigned int flags) 757 struct pipe_inode_info *pipe, size_t len,
758 unsigned int flags)
754{ 759{
755 loff_t pos, isize, left; 760 loff_t isize, left;
756 int ret; 761 int ret;
757 762
758 if (unlikely(!in->f_op || !in->f_op->splice_read)) 763 if (unlikely(!in->f_op || !in->f_op->splice_read))
@@ -761,28 +766,27 @@ static long do_splice_to(struct file *in, struct pipe_inode_info *pipe,
761 if (unlikely(!(in->f_mode & FMODE_READ))) 766 if (unlikely(!(in->f_mode & FMODE_READ)))
762 return -EBADF; 767 return -EBADF;
763 768
764 pos = in->f_pos; 769 ret = rw_verify_area(READ, in, ppos, len);
765
766 ret = rw_verify_area(READ, in, &pos, len);
767 if (unlikely(ret < 0)) 770 if (unlikely(ret < 0))
768 return ret; 771 return ret;
769 772
770 isize = i_size_read(in->f_mapping->host); 773 isize = i_size_read(in->f_mapping->host);
771 if (unlikely(in->f_pos >= isize)) 774 if (unlikely(*ppos >= isize))
772 return 0; 775 return 0;
773 776
774 left = isize - in->f_pos; 777 left = isize - *ppos;
775 if (unlikely(left < len)) 778 if (unlikely(left < len))
776 len = left; 779 len = left;
777 780
778 return in->f_op->splice_read(in, pipe, len, flags); 781 return in->f_op->splice_read(in, ppos, pipe, len, flags);
779} 782}
780 783
781long do_splice_direct(struct file *in, struct file *out, size_t len, 784long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
782 unsigned int flags) 785 size_t len, unsigned int flags)
783{ 786{
784 struct pipe_inode_info *pipe; 787 struct pipe_inode_info *pipe;
785 long ret, bytes; 788 long ret, bytes;
789 loff_t out_off;
786 umode_t i_mode; 790 umode_t i_mode;
787 int i; 791 int i;
788 792
@@ -820,6 +824,7 @@ long do_splice_direct(struct file *in, struct file *out, size_t len,
820 */ 824 */
821 ret = 0; 825 ret = 0;
822 bytes = 0; 826 bytes = 0;
827 out_off = 0;
823 828
824 while (len) { 829 while (len) {
825 size_t read_len, max_read_len; 830 size_t read_len, max_read_len;
@@ -829,7 +834,7 @@ long do_splice_direct(struct file *in, struct file *out, size_t len,
829 */ 834 */
830 max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE)); 835 max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE));
831 836
832 ret = do_splice_to(in, pipe, max_read_len, flags); 837 ret = do_splice_to(in, ppos, pipe, max_read_len, flags);
833 if (unlikely(ret < 0)) 838 if (unlikely(ret < 0))
834 goto out_release; 839 goto out_release;
835 840
@@ -840,7 +845,7 @@ long do_splice_direct(struct file *in, struct file *out, size_t len,
840 * must not do the output in nonblocking mode as then we 845 * must not do the output in nonblocking mode as then we
841 * could get stuck data in the internal pipe: 846 * could get stuck data in the internal pipe:
842 */ 847 */
843 ret = do_splice_from(pipe, out, read_len, 848 ret = do_splice_from(pipe, out, &out_off, read_len,
844 flags & ~SPLICE_F_NONBLOCK); 849 flags & ~SPLICE_F_NONBLOCK);
845 if (unlikely(ret < 0)) 850 if (unlikely(ret < 0))
846 goto out_release; 851 goto out_release;
@@ -898,6 +903,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
898 size_t len, unsigned int flags) 903 size_t len, unsigned int flags)
899{ 904{
900 struct pipe_inode_info *pipe; 905 struct pipe_inode_info *pipe;
906 loff_t offset, *off;
901 907
902 pipe = in->f_dentry->d_inode->i_pipe; 908 pipe = in->f_dentry->d_inode->i_pipe;
903 if (pipe) { 909 if (pipe) {
@@ -906,12 +912,13 @@ static long do_splice(struct file *in, loff_t __user *off_in,
906 if (off_out) { 912 if (off_out) {
907 if (out->f_op->llseek == no_llseek) 913 if (out->f_op->llseek == no_llseek)
908 return -EINVAL; 914 return -EINVAL;
909 if (copy_from_user(&out->f_pos, off_out, 915 if (copy_from_user(&offset, off_out, sizeof(loff_t)))
910 sizeof(loff_t)))
911 return -EFAULT; 916 return -EFAULT;
912 } 917 off = &offset;
918 } else
919 off = &out->f_pos;
913 920
914 return do_splice_from(pipe, out, len, flags); 921 return do_splice_from(pipe, out, off, len, flags);
915 } 922 }
916 923
917 pipe = out->f_dentry->d_inode->i_pipe; 924 pipe = out->f_dentry->d_inode->i_pipe;
@@ -921,11 +928,13 @@ static long do_splice(struct file *in, loff_t __user *off_in,
921 if (off_in) { 928 if (off_in) {
922 if (in->f_op->llseek == no_llseek) 929 if (in->f_op->llseek == no_llseek)
923 return -EINVAL; 930 return -EINVAL;
924 if (copy_from_user(&in->f_pos, off_in, sizeof(loff_t))) 931 if (copy_from_user(&offset, off_in, sizeof(loff_t)))
925 return -EFAULT; 932 return -EFAULT;
926 } 933 off = &offset;
934 } else
935 off = &in->f_pos;
927 936
928 return do_splice_to(in, pipe, len, flags); 937 return do_splice_to(in, off, pipe, len, flags);
929 } 938 }
930 939
931 return -EINVAL; 940 return -EINVAL;
@@ -961,3 +970,182 @@ asmlinkage long sys_splice(int fd_in, loff_t __user *off_in,
961 970
962 return error; 971 return error;
963} 972}
973
974/*
975 * Link contents of ipipe to opipe.
976 */
977static int link_pipe(struct pipe_inode_info *ipipe,
978 struct pipe_inode_info *opipe,
979 size_t len, unsigned int flags)
980{
981 struct pipe_buffer *ibuf, *obuf;
982 int ret = 0, do_wakeup = 0, i;
983
984 /*
985 * Potential ABBA deadlock, work around it by ordering lock
986 * grabbing by inode address. Otherwise two different processes
987 * could deadlock (one doing tee from A -> B, the other from B -> A).
988 */
989 if (ipipe->inode < opipe->inode) {
990 mutex_lock(&ipipe->inode->i_mutex);
991 mutex_lock(&opipe->inode->i_mutex);
992 } else {
993 mutex_lock(&opipe->inode->i_mutex);
994 mutex_lock(&ipipe->inode->i_mutex);
995 }
996
997 for (i = 0;; i++) {
998 if (!opipe->readers) {
999 send_sig(SIGPIPE, current, 0);
1000 if (!ret)
1001 ret = -EPIPE;
1002 break;
1003 }
1004 if (ipipe->nrbufs - i) {
1005 ibuf = ipipe->bufs + ((ipipe->curbuf + i) & (PIPE_BUFFERS - 1));
1006
1007 /*
1008 * If we have room, fill this buffer
1009 */
1010 if (opipe->nrbufs < PIPE_BUFFERS) {
1011 int nbuf = (opipe->curbuf + opipe->nrbufs) & (PIPE_BUFFERS - 1);
1012
1013 /*
1014 * Get a reference to this pipe buffer,
1015 * so we can copy the contents over.
1016 */
1017 ibuf->ops->get(ipipe, ibuf);
1018
1019 obuf = opipe->bufs + nbuf;
1020 *obuf = *ibuf;
1021
1022 if (obuf->len > len)
1023 obuf->len = len;
1024
1025 opipe->nrbufs++;
1026 do_wakeup = 1;
1027 ret += obuf->len;
1028 len -= obuf->len;
1029
1030 if (!len)
1031 break;
1032 if (opipe->nrbufs < PIPE_BUFFERS)
1033 continue;
1034 }
1035
1036 /*
1037 * We have input available, but no output room.
1038 * If we already copied data, return that.
1039 */
1040 if (flags & SPLICE_F_NONBLOCK) {
1041 if (!ret)
1042 ret = -EAGAIN;
1043 break;
1044 }
1045 if (signal_pending(current)) {
1046 if (!ret)
1047 ret = -ERESTARTSYS;
1048 break;
1049 }
1050 if (do_wakeup) {
1051 smp_mb();
1052 if (waitqueue_active(&opipe->wait))
1053 wake_up_interruptible(&opipe->wait);
1054 kill_fasync(&opipe->fasync_readers, SIGIO, POLL_IN);
1055 do_wakeup = 0;
1056 }
1057
1058 opipe->waiting_writers++;
1059 pipe_wait(opipe);
1060 opipe->waiting_writers--;
1061 continue;
1062 }
1063
1064 /*
1065 * No input buffers, do the usual checks for available
1066 * writers and blocking and wait if necessary
1067 */
1068 if (!ipipe->writers)
1069 break;
1070 if (!ipipe->waiting_writers) {
1071 if (ret)
1072 break;
1073 }
1074 if (flags & SPLICE_F_NONBLOCK) {
1075 if (!ret)
1076 ret = -EAGAIN;
1077 break;
1078 }
1079 if (signal_pending(current)) {
1080 if (!ret)
1081 ret = -ERESTARTSYS;
1082 break;
1083 }
1084
1085 if (waitqueue_active(&ipipe->wait))
1086 wake_up_interruptible_sync(&ipipe->wait);
1087 kill_fasync(&ipipe->fasync_writers, SIGIO, POLL_OUT);
1088
1089 pipe_wait(ipipe);
1090 }
1091
1092 mutex_unlock(&ipipe->inode->i_mutex);
1093 mutex_unlock(&opipe->inode->i_mutex);
1094
1095 if (do_wakeup) {
1096 smp_mb();
1097 if (waitqueue_active(&opipe->wait))
1098 wake_up_interruptible(&opipe->wait);
1099 kill_fasync(&opipe->fasync_readers, SIGIO, POLL_IN);
1100 }
1101
1102 return ret;
1103}
1104
1105/*
1106 * This is a tee(1) implementation that works on pipes. It doesn't copy
1107 * any data, it simply references the 'in' pages on the 'out' pipe.
1108 * The 'flags' used are the SPLICE_F_* variants, currently the only
1109 * applicable one is SPLICE_F_NONBLOCK.
1110 */
1111static long do_tee(struct file *in, struct file *out, size_t len,
1112 unsigned int flags)
1113{
1114 struct pipe_inode_info *ipipe = in->f_dentry->d_inode->i_pipe;
1115 struct pipe_inode_info *opipe = out->f_dentry->d_inode->i_pipe;
1116
1117 /*
1118 * Link ipipe to the two output pipes, consuming as we go along.
1119 */
1120 if (ipipe && opipe)
1121 return link_pipe(ipipe, opipe, len, flags);
1122
1123 return -EINVAL;
1124}
1125
1126asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags)
1127{
1128 struct file *in;
1129 int error, fput_in;
1130
1131 if (unlikely(!len))
1132 return 0;
1133
1134 error = -EBADF;
1135 in = fget_light(fdin, &fput_in);
1136 if (in) {
1137 if (in->f_mode & FMODE_READ) {
1138 int fput_out;
1139 struct file *out = fget_light(fdout, &fput_out);
1140
1141 if (out) {
1142 if (out->f_mode & FMODE_WRITE)
1143 error = do_tee(in, out, len, flags);
1144 fput_light(out, fput_out);
1145 }
1146 }
1147 fput_light(in, fput_in);
1148 }
1149
1150 return error;
1151}