Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+20 -4
+20 -4
fs/read_write.c
··· 15 15 #include <linux/module.h> 16 16 #include <linux/syscalls.h> 17 17 #include <linux/pagemap.h> 18 + #include <linux/pipe_fs_i.h> 18 19 #include "read_write.h" 19 20 20 21 #include <asm/uaccess.h> ··· 26 25 .read = do_sync_read, 27 26 .aio_read = generic_file_aio_read, 28 27 .mmap = generic_file_readonly_mmap, 29 - .sendfile = generic_file_sendfile, 28 + .splice_read = generic_file_splice_read, 30 29 }; 31 30 32 31 EXPORT_SYMBOL(generic_ro_fops); ··· 709 708 struct inode * in_inode, * out_inode; 710 709 loff_t pos; 711 710 ssize_t retval; 712 - int fput_needed_in, fput_needed_out; 711 + int fput_needed_in, fput_needed_out, fl; 713 712 714 713 /* 715 714 * Get input file, and verify that it is ok.. ··· 724 723 in_inode = in_file->f_path.dentry->d_inode; 725 724 if (!in_inode) 726 725 goto fput_in; 727 - if (!in_file->f_op || !in_file->f_op->sendfile) 726 + if (!in_file->f_op || (!in_file->f_op->sendfile && 727 + !in_file->f_op->splice_read)) 728 728 goto fput_in; 729 729 retval = -ESPIPE; 730 730 if (!ppos) ··· 778 776 count = max - pos; 779 777 } 780 778 781 - retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file); 779 + if (in_file->f_op->splice_read) { 780 + fl = 0; 781 + #if 0 782 + /* 783 + * We need to debate whether we can enable this or not. The 784 + * man page documents EAGAIN return for the output at least, 785 + * and the application is arguably buggy if it doesn't expect 786 + * EAGAIN on a non-blocking file descriptor. 787 + */ 788 + if (in_file->f_flags & O_NONBLOCK) 789 + fl = SPLICE_F_NONBLOCK; 790 + #endif 791 + retval = do_splice_direct(in_file, ppos, out_file, count, fl); 792 + } else 793 + retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file); 782 794 783 795 if (retval > 0) { 784 796 add_rchar(current, retval);