teach sendfile(2) to handle send-to-pipe directly
no point going through the intermediate pipe Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
faa97c48c3
commit
b964bf53e5
@ -15,6 +15,7 @@ struct mount;
|
|||||||
struct shrink_control;
|
struct shrink_control;
|
||||||
struct fs_context;
|
struct fs_context;
|
||||||
struct user_namespace;
|
struct user_namespace;
|
||||||
|
struct pipe_inode_info;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* block_dev.c
|
* block_dev.c
|
||||||
@ -193,3 +194,11 @@ int sb_init_dio_done_wq(struct super_block *sb);
|
|||||||
*/
|
*/
|
||||||
int do_statx(int dfd, const char __user *filename, unsigned flags,
|
int do_statx(int dfd, const char __user *filename, unsigned flags,
|
||||||
unsigned int mask, struct statx __user *buffer);
|
unsigned int mask, struct statx __user *buffer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fs/splice.c:
|
||||||
|
*/
|
||||||
|
long splice_file_to_pipe(struct file *in,
|
||||||
|
struct pipe_inode_info *opipe,
|
||||||
|
loff_t *offset,
|
||||||
|
size_t len, unsigned int flags);
|
||||||
|
@ -1188,6 +1188,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
|
|||||||
{
|
{
|
||||||
struct fd in, out;
|
struct fd in, out;
|
||||||
struct inode *in_inode, *out_inode;
|
struct inode *in_inode, *out_inode;
|
||||||
|
struct pipe_inode_info *opipe;
|
||||||
loff_t pos;
|
loff_t pos;
|
||||||
loff_t out_pos;
|
loff_t out_pos;
|
||||||
ssize_t retval;
|
ssize_t retval;
|
||||||
@ -1228,9 +1229,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
|
|||||||
in_inode = file_inode(in.file);
|
in_inode = file_inode(in.file);
|
||||||
out_inode = file_inode(out.file);
|
out_inode = file_inode(out.file);
|
||||||
out_pos = out.file->f_pos;
|
out_pos = out.file->f_pos;
|
||||||
retval = rw_verify_area(WRITE, out.file, &out_pos, count);
|
|
||||||
if (retval < 0)
|
|
||||||
goto fput_out;
|
|
||||||
|
|
||||||
if (!max)
|
if (!max)
|
||||||
max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
|
max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
|
||||||
@ -1253,9 +1251,18 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
|
|||||||
if (in.file->f_flags & O_NONBLOCK)
|
if (in.file->f_flags & O_NONBLOCK)
|
||||||
fl = SPLICE_F_NONBLOCK;
|
fl = SPLICE_F_NONBLOCK;
|
||||||
#endif
|
#endif
|
||||||
|
opipe = get_pipe_info(out.file, true);
|
||||||
|
if (!opipe) {
|
||||||
|
retval = rw_verify_area(WRITE, out.file, &out_pos, count);
|
||||||
|
if (retval < 0)
|
||||||
|
goto fput_out;
|
||||||
file_start_write(out.file);
|
file_start_write(out.file);
|
||||||
retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl);
|
retval = do_splice_direct(in.file, &pos, out.file, &out_pos,
|
||||||
|
count, fl);
|
||||||
file_end_write(out.file);
|
file_end_write(out.file);
|
||||||
|
} else {
|
||||||
|
retval = splice_file_to_pipe(in.file, opipe, &pos, count, fl);
|
||||||
|
}
|
||||||
|
|
||||||
if (retval > 0) {
|
if (retval > 0) {
|
||||||
add_rchar(current, retval);
|
add_rchar(current, retval);
|
||||||
|
@ -1002,7 +1002,7 @@ static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
|
|||||||
struct pipe_inode_info *opipe,
|
struct pipe_inode_info *opipe,
|
||||||
size_t len, unsigned int flags);
|
size_t len, unsigned int flags);
|
||||||
|
|
||||||
static long splice_file_to_pipe(struct file *in,
|
long splice_file_to_pipe(struct file *in,
|
||||||
struct pipe_inode_info *opipe,
|
struct pipe_inode_info *opipe,
|
||||||
loff_t *offset,
|
loff_t *offset,
|
||||||
size_t len, unsigned int flags)
|
size_t len, unsigned int flags)
|
||||||
|
Loading…
Reference in New Issue
Block a user