diff options
| author | Jens Axboe <jens.axboe@oracle.com> | 2007-06-01 08:52:37 -0400 |
|---|---|---|
| committer | Jens Axboe <jens.axboe@oracle.com> | 2007-07-10 02:04:12 -0400 |
| commit | 534f2aaa6ab07cd71164180bc958a7dcde41db11 (patch) | |
| tree | 4c2557f4c4c3913bbc5e282c98559ef70b92fd4b | |
| parent | 6a14b90bb6bc7cd83e2a444bf457a2ea645cbfe7 (diff) | |
sys_sendfile: switch to using ->splice_read, if available
This patch makes sendfile prefer to use ->splice_read(), if it's
available in the file_operations structure.
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
| -rw-r--r-- | fs/read_write.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/fs/read_write.c b/fs/read_write.c index 4d03008f015b..47da8a4a0fbe 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/syscalls.h> | 16 | #include <linux/syscalls.h> |
| 17 | #include <linux/pagemap.h> | 17 | #include <linux/pagemap.h> |
| 18 | #include <linux/pipe_fs_i.h> | ||
| 18 | #include "read_write.h" | 19 | #include "read_write.h" |
| 19 | 20 | ||
| 20 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
| @@ -25,7 +26,7 @@ const struct file_operations generic_ro_fops = { | |||
| 25 | .read = do_sync_read, | 26 | .read = do_sync_read, |
| 26 | .aio_read = generic_file_aio_read, | 27 | .aio_read = generic_file_aio_read, |
| 27 | .mmap = generic_file_readonly_mmap, | 28 | .mmap = generic_file_readonly_mmap, |
| 28 | .sendfile = generic_file_sendfile, | 29 | .splice_read = generic_file_splice_read, |
| 29 | }; | 30 | }; |
| 30 | 31 | ||
| 31 | EXPORT_SYMBOL(generic_ro_fops); | 32 | EXPORT_SYMBOL(generic_ro_fops); |
| @@ -708,7 +709,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
| 708 | struct inode * in_inode, * out_inode; | 709 | struct inode * in_inode, * out_inode; |
| 709 | loff_t pos; | 710 | loff_t pos; |
| 710 | ssize_t retval; | 711 | ssize_t retval; |
| 711 | int fput_needed_in, fput_needed_out; | 712 | int fput_needed_in, fput_needed_out, fl; |
| 712 | 713 | ||
| 713 | /* | 714 | /* |
| 714 | * Get input file, and verify that it is ok.. | 715 | * Get input file, and verify that it is ok.. |
| @@ -723,7 +724,8 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
| 723 | in_inode = in_file->f_path.dentry->d_inode; | 724 | in_inode = in_file->f_path.dentry->d_inode; |
| 724 | if (!in_inode) | 725 | if (!in_inode) |
| 725 | goto fput_in; | 726 | goto fput_in; |
| 726 | if (!in_file->f_op || !in_file->f_op->sendfile) | 727 | if (!in_file->f_op || (!in_file->f_op->sendfile && |
| 728 | !in_file->f_op->splice_read)) | ||
| 727 | goto fput_in; | 729 | goto fput_in; |
| 728 | retval = -ESPIPE; | 730 | retval = -ESPIPE; |
| 729 | if (!ppos) | 731 | if (!ppos) |
| @@ -776,7 +778,21 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
| 776 | count = max - pos; | 778 | count = max - pos; |
| 777 | } | 779 | } |
| 778 | 780 | ||
| 779 | retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file); | 781 | if (in_file->f_op->splice_read) { |
| 782 | fl = 0; | ||
| 783 | #if 0 | ||
| 784 | /* | ||
| 785 | * We need to debate whether we can enable this or not. The | ||
| 786 | * man page documents EAGAIN return for the output at least, | ||
| 787 | * and the application is arguably buggy if it doesn't expect | ||
| 788 | * EAGAIN on a non-blocking file descriptor. | ||
| 789 | */ | ||
| 790 | if (in_file->f_flags & O_NONBLOCK) | ||
| 791 | fl = SPLICE_F_NONBLOCK; | ||
| 792 | #endif | ||
| 793 | retval = do_splice_direct(in_file, ppos, out_file, count, fl); | ||
| 794 | } else | ||
| 795 | retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file); | ||
| 780 | 796 | ||
| 781 | if (retval > 0) { | 797 | if (retval > 0) { |
| 782 | add_rchar(current, retval); | 798 | add_rchar(current, retval); |
