aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2006-04-11 08:57:50 -0400
committerJens Axboe <axboe@nelson.home.kernel.dk>2006-04-11 09:47:07 -0400
commitcbb7e577e732f576b9f399bc2600bdc0626c68dc (patch)
tree55e3d65c9d9fb5b0ee25d0ccabf951de6da2db7b
parent2514395ef88b46e895726a8d40966cb83de7940c (diff)
[PATCH] splice: pass offset around for ->splice_read() and ->splice_write()
We need not use ->f_pos as the offset for the file input/output. If the user passed an offset pointer in through sys_splice(), just use that and leave ->f_pos alone. Signed-off-by: Jens Axboe <axboe@suse.de>
-rw-r--r--fs/splice.c86
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c12
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h4
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h12
-rw-r--r--include/linux/fs.h12
6 files changed, 74 insertions, 66 deletions
diff --git a/fs/splice.c b/fs/splice.c
index e50a460239..5d3eda6470 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -231,8 +231,9 @@ static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages,
231} 231}
232 232
233static int 233static int
234__generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe, 234__generic_file_splice_read(struct file *in, loff_t *ppos,
235 size_t len, unsigned int flags) 235 struct pipe_inode_info *pipe, size_t len,
236 unsigned int flags)
236{ 237{
237 struct address_space *mapping = in->f_mapping; 238 struct address_space *mapping = in->f_mapping;
238 unsigned int offset, nr_pages; 239 unsigned int offset, nr_pages;
@@ -241,8 +242,8 @@ __generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe,
241 pgoff_t index; 242 pgoff_t index;
242 int i, error; 243 int i, error;
243 244
244 index = in->f_pos >> PAGE_CACHE_SHIFT; 245 index = *ppos >> PAGE_CACHE_SHIFT;
245 offset = in->f_pos & ~PAGE_CACHE_MASK; 246 offset = *ppos & ~PAGE_CACHE_MASK;
246 nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 247 nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
247 248
248 if (nr_pages > PIPE_BUFFERS) 249 if (nr_pages > PIPE_BUFFERS)
@@ -348,8 +349,9 @@ fill_it:
348 * 349 *
349 * Will read pages from given file and fill them into a pipe. 350 * Will read pages from given file and fill them into a pipe.
350 */ 351 */
351ssize_t generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe, 352ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
352 size_t len, unsigned int flags) 353 struct pipe_inode_info *pipe, size_t len,
354 unsigned int flags)
353{ 355{
354 ssize_t spliced; 356 ssize_t spliced;
355 int ret; 357 int ret;
@@ -358,12 +360,12 @@ ssize_t generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe,
358 spliced = 0; 360 spliced = 0;
359 361
360 while (len) { 362 while (len) {
361 ret = __generic_file_splice_read(in, pipe, len, flags); 363 ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
362 364
363 if (ret <= 0) 365 if (ret <= 0)
364 break; 366 break;
365 367
366 in->f_pos += ret; 368 *ppos += ret;
367 len -= ret; 369 len -= ret;
368 spliced += ret; 370 spliced += ret;
369 371
@@ -561,7 +563,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. 563 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
562 */ 564 */
563static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, 565static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out,
564 size_t len, unsigned int flags, 566 loff_t *ppos, size_t len, unsigned int flags,
565 splice_actor *actor) 567 splice_actor *actor)
566{ 568{
567 int ret, do_wakeup, err; 569 int ret, do_wakeup, err;
@@ -573,7 +575,7 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out,
573 sd.total_len = len; 575 sd.total_len = len;
574 sd.flags = flags; 576 sd.flags = flags;
575 sd.file = out; 577 sd.file = out;
576 sd.pos = out->f_pos; 578 sd.pos = *ppos;
577 579
578 if (pipe->inode) 580 if (pipe->inode)
579 mutex_lock(&pipe->inode->i_mutex); 581 mutex_lock(&pipe->inode->i_mutex);
@@ -656,9 +658,7 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out,
656 kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); 658 kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
657 } 659 }
658 660
659 out->f_pos = sd.pos;
660 return ret; 661 return ret;
661
662} 662}
663 663
664/** 664/**
@@ -674,12 +674,12 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out,
674 */ 674 */
675ssize_t 675ssize_t
676generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, 676generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
677 size_t len, unsigned int flags) 677 loff_t *ppos, size_t len, unsigned int flags)
678{ 678{
679 struct address_space *mapping = out->f_mapping; 679 struct address_space *mapping = out->f_mapping;
680 ssize_t ret; 680 ssize_t ret;
681 681
682 ret = move_from_pipe(pipe, out, len, flags, pipe_to_file); 682 ret = move_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
683 683
684 /* 684 /*
685 * If file or inode is SYNC and we actually wrote some data, sync it. 685 * If file or inode is SYNC and we actually wrote some data, sync it.
@@ -715,9 +715,9 @@ EXPORT_SYMBOL(generic_file_splice_write);
715 * 715 *
716 */ 716 */
717ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, 717ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out,
718 size_t len, unsigned int flags) 718 loff_t *ppos, size_t len, unsigned int flags)
719{ 719{
720 return move_from_pipe(pipe, out, len, flags, pipe_to_sendpage); 720 return move_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage);
721} 721}
722 722
723EXPORT_SYMBOL(generic_splice_sendpage); 723EXPORT_SYMBOL(generic_splice_sendpage);
@@ -726,9 +726,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
726 * Attempt to initiate a splice from pipe to file. 726 * Attempt to initiate a splice from pipe to file.
727 */ 727 */
728static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, 728static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
729 size_t len, unsigned int flags) 729 loff_t *ppos, size_t len, unsigned int flags)
730{ 730{
731 loff_t pos;
732 int ret; 731 int ret;
733 732
734 if (unlikely(!out->f_op || !out->f_op->splice_write)) 733 if (unlikely(!out->f_op || !out->f_op->splice_write))
@@ -737,22 +736,21 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
737 if (unlikely(!(out->f_mode & FMODE_WRITE))) 736 if (unlikely(!(out->f_mode & FMODE_WRITE)))
738 return -EBADF; 737 return -EBADF;
739 738
740 pos = out->f_pos; 739 ret = rw_verify_area(WRITE, out, ppos, len);
741
742 ret = rw_verify_area(WRITE, out, &pos, len);
743 if (unlikely(ret < 0)) 740 if (unlikely(ret < 0))
744 return ret; 741 return ret;
745 742
746 return out->f_op->splice_write(pipe, out, len, flags); 743 return out->f_op->splice_write(pipe, out, ppos, len, flags);
747} 744}
748 745
749/* 746/*
750 * Attempt to initiate a splice from a file to a pipe. 747 * Attempt to initiate a splice from a file to a pipe.
751 */ 748 */
752static long do_splice_to(struct file *in, struct pipe_inode_info *pipe, 749static long do_splice_to(struct file *in, loff_t *ppos,
753 size_t len, unsigned int flags) 750 struct pipe_inode_info *pipe, size_t len,
751 unsigned int flags)
754{ 752{
755 loff_t pos, isize, left; 753 loff_t isize, left;
756 int ret; 754 int ret;
757 755
758 if (unlikely(!in->f_op || !in->f_op->splice_read)) 756 if (unlikely(!in->f_op || !in->f_op->splice_read))
@@ -761,28 +759,27 @@ static long do_splice_to(struct file *in, struct pipe_inode_info *pipe,
761 if (unlikely(!(in->f_mode & FMODE_READ))) 759 if (unlikely(!(in->f_mode & FMODE_READ)))
762 return -EBADF; 760 return -EBADF;
763 761
764 pos = in->f_pos; 762 ret = rw_verify_area(READ, in, ppos, len);
765
766 ret = rw_verify_area(READ, in, &pos, len);
767 if (unlikely(ret < 0)) 763 if (unlikely(ret < 0))
768 return ret; 764 return ret;
769 765
770 isize = i_size_read(in->f_mapping->host); 766 isize = i_size_read(in->f_mapping->host);
771 if (unlikely(in->f_pos >= isize)) 767 if (unlikely(*ppos >= isize))
772 return 0; 768 return 0;
773 769
774 left = isize - in->f_pos; 770 left = isize - *ppos;
775 if (unlikely(left < len)) 771 if (unlikely(left < len))
776 len = left; 772 len = left;
777 773
778 return in->f_op->splice_read(in, pipe, len, flags); 774 return in->f_op->splice_read(in, ppos, pipe, len, flags);
779} 775}
780 776
781long do_splice_direct(struct file *in, struct file *out, size_t len, 777long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
782 unsigned int flags) 778 size_t len, unsigned int flags)
783{ 779{
784 struct pipe_inode_info *pipe; 780 struct pipe_inode_info *pipe;
785 long ret, bytes; 781 long ret, bytes;
782 loff_t out_off;
786 umode_t i_mode; 783 umode_t i_mode;
787 int i; 784 int i;
788 785
@@ -820,6 +817,7 @@ long do_splice_direct(struct file *in, struct file *out, size_t len,