diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-12-01 04:56:43 -0500 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-12-01 04:56:43 -0500 |
commit | bd3c97a7c718bfb9f1e4f31c16c383a5c6f815eb (patch) | |
tree | 3f56594e813c6f35cbacbdb3e137ba5bfd0b3069 /fs/splice.c | |
parent | 6c33cafc794d07c9254c160789120a0e98c088c9 (diff) | |
parent | 0215ffb08ce99e2bb59eca114a99499a4d06e704 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'fs/splice.c')
-rw-r--r-- | fs/splice.c | 140 |
1 files changed, 107 insertions, 33 deletions
diff --git a/fs/splice.c b/fs/splice.c index a567010b62ac..da74583a00ee 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -74,7 +74,7 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe, | |||
74 | wait_on_page_writeback(page); | 74 | wait_on_page_writeback(page); |
75 | 75 | ||
76 | if (PagePrivate(page)) | 76 | if (PagePrivate(page)) |
77 | try_to_release_page(page, mapping_gfp_mask(mapping)); | 77 | try_to_release_page(page, GFP_KERNEL); |
78 | 78 | ||
79 | /* | 79 | /* |
80 | * If we succeeded in removing the mapping, set LRU flag | 80 | * If we succeeded in removing the mapping, set LRU flag |
@@ -333,7 +333,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
333 | break; | 333 | break; |
334 | 334 | ||
335 | error = add_to_page_cache_lru(page, mapping, index, | 335 | error = add_to_page_cache_lru(page, mapping, index, |
336 | mapping_gfp_mask(mapping)); | 336 | GFP_KERNEL); |
337 | if (unlikely(error)) { | 337 | if (unlikely(error)) { |
338 | page_cache_release(page); | 338 | page_cache_release(page); |
339 | if (error == -EEXIST) | 339 | if (error == -EEXIST) |
@@ -557,7 +557,6 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | |||
557 | { | 557 | { |
558 | struct file *file = sd->file; | 558 | struct file *file = sd->file; |
559 | struct address_space *mapping = file->f_mapping; | 559 | struct address_space *mapping = file->f_mapping; |
560 | gfp_t gfp_mask = mapping_gfp_mask(mapping); | ||
561 | unsigned int offset, this_len; | 560 | unsigned int offset, this_len; |
562 | struct page *page; | 561 | struct page *page; |
563 | pgoff_t index; | 562 | pgoff_t index; |
@@ -591,7 +590,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | |||
591 | goto find_page; | 590 | goto find_page; |
592 | 591 | ||
593 | page = buf->page; | 592 | page = buf->page; |
594 | if (add_to_page_cache(page, mapping, index, gfp_mask)) { | 593 | if (add_to_page_cache(page, mapping, index, GFP_KERNEL)) { |
595 | unlock_page(page); | 594 | unlock_page(page); |
596 | goto find_page; | 595 | goto find_page; |
597 | } | 596 | } |
@@ -613,7 +612,7 @@ find_page: | |||
613 | * This will also lock the page | 612 | * This will also lock the page |
614 | */ | 613 | */ |
615 | ret = add_to_page_cache_lru(page, mapping, index, | 614 | ret = add_to_page_cache_lru(page, mapping, index, |
616 | gfp_mask); | 615 | GFP_KERNEL); |
617 | if (unlikely(ret)) | 616 | if (unlikely(ret)) |
618 | goto out; | 617 | goto out; |
619 | } | 618 | } |
@@ -707,9 +706,9 @@ out_ret: | |||
707 | * key here is the 'actor' worker passed in that actually moves the data | 706 | * 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. | 707 | * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. |
709 | */ | 708 | */ |
710 | ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, | 709 | static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, |
711 | loff_t *ppos, size_t len, unsigned int flags, | 710 | struct file *out, loff_t *ppos, size_t len, |
712 | splice_actor *actor) | 711 | unsigned int flags, splice_actor *actor) |
713 | { | 712 | { |
714 | int ret, do_wakeup, err; | 713 | int ret, do_wakeup, err; |
715 | struct splice_desc sd; | 714 | struct splice_desc sd; |
@@ -722,9 +721,6 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, | |||
722 | sd.file = out; | 721 | sd.file = out; |
723 | sd.pos = *ppos; | 722 | sd.pos = *ppos; |
724 | 723 | ||
725 | if (pipe->inode) | ||
726 | mutex_lock(&pipe->inode->i_mutex); | ||
727 | |||
728 | for (;;) { | 724 | for (;;) { |
729 | if (pipe->nrbufs) { | 725 | if (pipe->nrbufs) { |
730 | struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; | 726 | struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; |
@@ -797,9 +793,6 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, | |||
797 | pipe_wait(pipe); | 793 | pipe_wait(pipe); |
798 | } | 794 | } |
799 | 795 | ||
800 | if (pipe->inode) | ||
801 | mutex_unlock(&pipe->inode->i_mutex); | ||
802 | |||
803 | if (do_wakeup) { | 796 | if (do_wakeup) { |
804 | smp_mb(); | 797 | smp_mb(); |
805 | if (waitqueue_active(&pipe->wait)) | 798 | if (waitqueue_active(&pipe->wait)) |
@@ -810,6 +803,73 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, | |||
810 | return ret; | 803 | return ret; |
811 | } | 804 | } |
812 | 805 | ||
806 | ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, | ||
807 | loff_t *ppos, size_t len, unsigned int flags, | ||
808 | splice_actor *actor) | ||
809 | { | ||
810 | ssize_t ret; | ||
811 | struct inode *inode = out->f_mapping->host; | ||
812 | |||
813 | /* | ||
814 | * The actor worker might be calling ->prepare_write and | ||
815 | * ->commit_write. Most of the time, these expect i_mutex to | ||
816 | * be held. Since this may result in an ABBA deadlock with | ||
817 | * pipe->inode, we have to order lock acquiry here. | ||
818 | */ | ||
819 | inode_double_lock(inode, pipe->inode); | ||
820 | ret = __splice_from_pipe(pipe, out, ppos, len, flags, actor); | ||
821 | inode_double_unlock(inode, pipe->inode); | ||
822 | |||
823 | return ret; | ||
824 | } | ||
825 | |||
826 | /** | ||
827 | * generic_file_splice_write_nolock - generic_file_splice_write without mutexes | ||
828 | * @pipe: pipe info | ||
829 | * @out: file to write to | ||
830 | * @len: number of bytes to splice | ||
831 | * @flags: splice modifier flags | ||
832 | * | ||
833 | * Will either move or copy pages (determined by @flags options) from | ||
834 | * the given pipe inode to the given file. The caller is responsible | ||
835 | * for acquiring i_mutex on both inodes. | ||
836 | * | ||
837 | */ | ||
838 | ssize_t | ||
839 | generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out, | ||
840 | loff_t *ppos, size_t len, unsigned int flags) | ||
841 | { | ||
842 | struct address_space *mapping = out->f_mapping; | ||
843 | struct inode *inode = mapping->host; | ||
844 | ssize_t ret; | ||
845 | int err; | ||
846 | |||
847 | err = remove_suid(out->f_dentry); | ||
848 | if (unlikely(err)) | ||
849 | return err; | ||
850 | |||
851 | ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); | ||
852 | if (ret > 0) { | ||
853 | *ppos += ret; | ||
854 | |||
855 | /* | ||
856 | * If file or inode is SYNC and we actually wrote some data, | ||
857 | * sync it. | ||
858 | */ | ||
859 | if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) { | ||
860 | err = generic_osync_inode(inode, mapping, | ||
861 | OSYNC_METADATA|OSYNC_DATA); | ||
862 | |||
863 | if (err) | ||
864 | ret = err; | ||
865 | } | ||
866 | } | ||
867 | |||
868 | return ret; | ||
869 | } | ||
870 | |||
871 | EXPORT_SYMBOL(generic_file_splice_write_nolock); | ||
872 | |||
813 | /** | 873 | /** |
814 | * generic_file_splice_write - splice data from a pipe to a file | 874 | * generic_file_splice_write - splice data from a pipe to a file |
815 | * @pipe: pipe info | 875 | * @pipe: pipe info |
@@ -826,12 +886,21 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
826 | loff_t *ppos, size_t len, unsigned int flags) | 886 | loff_t *ppos, size_t len, unsigned int flags) |
827 | { | 887 | { |
828 | struct address_space *mapping = out->f_mapping; | 888 | struct address_space *mapping = out->f_mapping; |
889 | struct inode *inode = mapping->host; | ||
829 | ssize_t ret; | 890 | ssize_t ret; |
891 | int err; | ||
892 | |||
893 | err = should_remove_suid(out->f_dentry); | ||
894 | if (unlikely(err)) { | ||
895 | mutex_lock(&inode->i_mutex); | ||
896 | err = __remove_suid(out->f_dentry, err); | ||
897 | mutex_unlock(&inode->i_mutex); | ||
898 | if (err) | ||
899 | return err; | ||
900 | } | ||
830 | 901 | ||
831 | ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); | 902 | ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); |
832 | if (ret > 0) { | 903 | if (ret > 0) { |
833 | struct inode *inode = mapping->host; | ||
834 | |||
835 | *ppos += ret; | 904 | *ppos += ret; |
836 | 905 | ||
837 | /* | 906 | /* |
@@ -839,8 +908,6 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
839 | * sync it. | 908 | * sync it. |
840 | */ | 909 | */ |
841 | if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) { | 910 | if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) { |
842 | int err; | ||
843 | |||
844 | mutex_lock(&inode->i_mutex); | 911 | mutex_lock(&inode->i_mutex); |
845 | err = generic_osync_inode(inode, mapping, | 912 | err = generic_osync_inode(inode, mapping, |
846 | OSYNC_METADATA|OSYNC_DATA); | 913 | OSYNC_METADATA|OSYNC_DATA); |
@@ -1042,6 +1109,19 @@ out_release: | |||
1042 | EXPORT_SYMBOL(do_splice_direct); | 1109 | EXPORT_SYMBOL(do_splice_direct); |
1043 | 1110 | ||
1044 | /* | 1111 | /* |
1112 | * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same | ||
1113 | * location, so checking ->i_pipe is not enough to verify that this is a | ||
1114 | * pipe. | ||
1115 | */ | ||
1116 | static inline struct pipe_inode_info *pipe_info(struct inode *inode) | ||
1117 | { | ||
1118 | if (S_ISFIFO(inode->i_mode)) | ||
1119 | return inode->i_pipe; | ||
1120 | |||
1121 | return NULL; | ||
1122 | } | ||
1123 | |||
1124 | /* | ||
1045 | * Determine where to splice to/from. | 1125 | * Determine where to splice to/from. |
1046 | */ | 1126 | */ |
1047 | static long do_splice(struct file *in, loff_t __user *off_in, | 1127 | static long do_splice(struct file *in, loff_t __user *off_in, |
@@ -1052,7 +1132,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1052 | loff_t offset, *off; | 1132 | loff_t offset, *off; |
1053 | long ret; | 1133 | long ret; |
1054 | 1134 | ||
1055 | pipe = in->f_dentry->d_inode->i_pipe; | 1135 | pipe = pipe_info(in->f_dentry->d_inode); |
1056 | if (pipe) { | 1136 | if (pipe) { |
1057 | if (off_in) | 1137 | if (off_in) |
1058 | return -ESPIPE; | 1138 | return -ESPIPE; |
@@ -1073,7 +1153,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1073 | return ret; | 1153 | return ret; |
1074 | } | 1154 | } |
1075 | 1155 | ||
1076 | pipe = out->f_dentry->d_inode->i_pipe; | 1156 | pipe = pipe_info(out->f_dentry->d_inode); |
1077 | if (pipe) { | 1157 | if (pipe) { |
1078 | if (off_out) | 1158 | if (off_out) |
1079 | return -ESPIPE; | 1159 | return -ESPIPE; |
@@ -1231,7 +1311,7 @@ static int get_iovec_page_array(const struct iovec __user *iov, | |||
1231 | static long do_vmsplice(struct file *file, const struct iovec __user *iov, | 1311 | static long do_vmsplice(struct file *file, const struct iovec __user *iov, |
1232 | unsigned long nr_segs, unsigned int flags) | 1312 | unsigned long nr_segs, unsigned int flags) |
1233 | { | 1313 | { |
1234 | struct pipe_inode_info *pipe = file->f_dentry->d_inode->i_pipe; | 1314 | struct pipe_inode_info *pipe; |
1235 | struct page *pages[PIPE_BUFFERS]; | 1315 | struct page *pages[PIPE_BUFFERS]; |
1236 | struct partial_page partial[PIPE_BUFFERS]; | 1316 | struct partial_page partial[PIPE_BUFFERS]; |
1237 | struct splice_pipe_desc spd = { | 1317 | struct splice_pipe_desc spd = { |
@@ -1241,7 +1321,8 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov, | |||
1241 | .ops = &user_page_pipe_buf_ops, | 1321 | .ops = &user_page_pipe_buf_ops, |
1242 | }; | 1322 | }; |
1243 | 1323 | ||
1244 | if (unlikely(!pipe)) | 1324 | pipe = pipe_info(file->f_dentry->d_inode); |
1325 | if (!pipe) | ||
1245 | return -EBADF; | 1326 | return -EBADF; |
1246 | if (unlikely(nr_segs > UIO_MAXIOV)) | 1327 | if (unlikely(nr_segs > UIO_MAXIOV)) |
1247 | return -EINVAL; | 1328 | return -EINVAL; |
@@ -1400,13 +1481,7 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
1400 | * grabbing by inode address. Otherwise two different processes | 1481 | * grabbing by inode address. Otherwise two different processes |
1401 | * could deadlock (one doing tee from A -> B, the other from B -> A). | 1482 | * could deadlock (one doing tee from A -> B, the other from B -> A). |
1402 | */ | 1483 | */ |
1403 | if (ipipe->inode < opipe->inode) { | 1484 | inode_double_lock(ipipe->inode, opipe->inode); |
1404 | mutex_lock_nested(&ipipe->inode->i_mutex, I_MUTEX_PARENT); | ||
1405 | mutex_lock_nested(&opipe->inode->i_mutex, I_MUTEX_CHILD); | ||
1406 | } else { | ||
1407 | mutex_lock_nested(&opipe->inode->i_mutex, I_MUTEX_PARENT); | ||
1408 | mutex_lock_nested(&ipipe->inode->i_mutex, I_MUTEX_CHILD); | ||
1409 | } | ||
1410 | 1485 | ||
1411 | do { | 1486 | do { |
1412 | if (!opipe->readers) { | 1487 | if (!opipe->readers) { |
@@ -1450,8 +1525,7 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
1450 | i++; | 1525 | i++; |
1451 | } while (len); | 1526 | } while (len); |
1452 | 1527 | ||
1453 | mutex_unlock(&ipipe->inode->i_mutex); | 1528 | inode_double_unlock(ipipe->inode, opipe->inode); |
1454 | mutex_unlock(&opipe->inode->i_mutex); | ||
1455 | 1529 | ||
1456 | /* | 1530 | /* |
1457 | * If we put data in the output pipe, wakeup any potential readers. | 1531 | * If we put data in the output pipe, wakeup any potential readers. |
@@ -1475,8 +1549,8 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
1475 | static long do_tee(struct file *in, struct file *out, size_t len, | 1549 | static long do_tee(struct file *in, struct file *out, size_t len, |
1476 | unsigned int flags) | 1550 | unsigned int flags) |
1477 | { | 1551 | { |
1478 | struct pipe_inode_info *ipipe = in->f_dentry->d_inode->i_pipe; | 1552 | struct pipe_inode_info *ipipe = pipe_info(in->f_dentry->d_inode); |
1479 | struct pipe_inode_info *opipe = out->f_dentry->d_inode->i_pipe; | 1553 | struct pipe_inode_info *opipe = pipe_info(out->f_dentry->d_inode); |
1480 | int ret = -EINVAL; | 1554 | int ret = -EINVAL; |
1481 | 1555 | ||
1482 | /* | 1556 | /* |