aboutsummaryrefslogtreecommitdiffstats
path: root/fs/splice.c
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2006-10-17 12:43:07 -0400
committerJens Axboe <axboe@nelson.home.kernel.dk>2006-10-19 14:53:08 -0400
commit6da61809822c22634a3de2dcb3c60283b836a88a (patch)
tree80bc4105a4eabb221e5b1896b2c8b915a9c90d28 /fs/splice.c
parent62752ee198dca9209b7dee504763e51b11e9e0ca (diff)
[PATCH] Introduce generic_file_splice_write_nolock()
This allows file systems to manage their own i_mutex locking while still re-using the generic_file_splice_write() logic. OCFS2 in particular wants this so that it can order cluster locks within i_mutex. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs/splice.c')
-rw-r--r--fs/splice.c80
1 files changed, 66 insertions, 14 deletions
diff --git a/fs/splice.c b/fs/splice.c
index c1072b6940c3..68e20e65c6e1 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -707,13 +707,12 @@ out_ret:
707 * key here is the 'actor' worker passed in that actually moves the data 707 * key here is the 'actor' worker passed in that actually moves the data
708 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. 708 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
709 */ 709 */
710ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, 710static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
711 loff_t *ppos, size_t len, unsigned int flags, 711 struct file *out, loff_t *ppos, size_t len,
712 splice_actor *actor) 712 unsigned int flags, splice_actor *actor)
713{ 713{
714 int ret, do_wakeup, err; 714 int ret, do_wakeup, err;
715 struct splice_desc sd; 715 struct splice_desc sd;
716 struct inode *inode = out->f_mapping->host;
717 716
718 ret = 0; 717 ret = 0;
719 do_wakeup = 0; 718 do_wakeup = 0;
@@ -723,14 +722,6 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
723 sd.file = out; 722 sd.file = out;
724 sd.pos = *ppos; 723 sd.pos = *ppos;
725 724
726 /*
727 * The actor worker might be calling ->prepare_write and
728 * ->commit_write. Most of the time, these expect i_mutex to
729 * be held. Since this may result in an ABBA deadlock with
730 * pipe->inode, we have to order lock acquiry here.
731 */
732 inode_double_lock(inode, pipe->inode);
733
734 for (;;) { 725 for (;;) {
735 if (pipe->nrbufs) { 726 if (pipe->nrbufs) {
736 struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; 727 struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
@@ -803,8 +794,6 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
803 pipe_wait(pipe); 794 pipe_wait(pipe);
804 } 795 }
805 796
806 inode_double_unlock(inode, pipe->inode);
807
808 if (do_wakeup) { 797 if (do_wakeup) {
809 smp_mb(); 798 smp_mb();
810 if (waitqueue_active(&pipe->wait)) 799 if (waitqueue_active(&pipe->wait))
@@ -815,6 +804,69 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
815 return ret; 804 return ret;
816} 805}
817 806
807ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
808 loff_t *ppos, size_t len, unsigned int flags,
809 splice_actor *actor)
810{
811 ssize_t ret;
812 struct inode *inode = out->f_mapping->host;
813
814 /*
815 * The actor worker might be calling ->prepare_write and
816 * ->commit_write. Most of the time, these expect i_mutex to
817 * be held. Since this may result in an ABBA deadlock with
818 * pipe->inode, we have to order lock acquiry here.
819 */
820 inode_double_lock(inode, pipe->inode);
821 ret = __splice_from_pipe(pipe, out, ppos, len, flags, actor);
822 inode_double_unlock(inode, pipe->inode);
823
824 return ret;
825}
826
827/**
828 * generic_file_splice_write_nolock - generic_file_splice_write without mutexes
829 * @pipe: pipe info
830 * @out: file to write to
831 * @len: number of bytes to splice
832 * @flags: splice modifier flags
833 *
834 * Will either move or copy pages (determined by @flags options) from
835 * the given pipe inode to the given file. The caller is responsible
836 * for acquiring i_mutex on both inodes.
837 *
838 */
839ssize_t
840generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
841 loff_t *ppos, size_t len, unsigned int flags)
842{
843 struct address_space *mapping = out->f_mapping;
844 struct inode *inode = mapping->host;
845 ssize_t ret;
846 int err;
847
848 ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
849 if (ret > 0) {
850 *ppos += ret;
851
852 /*
853 * If file or inode is SYNC and we actually wrote some data,
854 * sync it.
855 */
856 if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
857 err = generic_osync_inode(inode, mapping,
858 OSYNC_METADATA|OSYNC_DATA);
859
860 if (err)
861 ret = err;
862 }
863 }
864
865 return ret;
866}
867
868EXPORT_SYMBOL(generic_file_splice_write_nolock);
869
818/** 870/**
819 * generic_file_splice_write - splice data from a pipe to a file 871 * generic_file_splice_write - splice data from a pipe to a file
820 * @pipe: pipe info 872 * @pipe: pipe info