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:
Родитель
faa97c48c3
Коммит
b964bf53e5
|
@ -15,6 +15,7 @@ struct mount;
|
|||
struct shrink_control;
|
||||
struct fs_context;
|
||||
struct user_namespace;
|
||||
struct pipe_inode_info;
|
||||
|
||||
/*
|
||||
* 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,
|
||||
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 inode *in_inode, *out_inode;
|
||||
struct pipe_inode_info *opipe;
|
||||
loff_t pos;
|
||||
loff_t out_pos;
|
||||
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);
|
||||
out_inode = file_inode(out.file);
|
||||
out_pos = out.file->f_pos;
|
||||
retval = rw_verify_area(WRITE, out.file, &out_pos, count);
|
||||
if (retval < 0)
|
||||
goto fput_out;
|
||||
|
||||
if (!max)
|
||||
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)
|
||||
fl = SPLICE_F_NONBLOCK;
|
||||
#endif
|
||||
file_start_write(out.file);
|
||||
retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl);
|
||||
file_end_write(out.file);
|
||||
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);
|
||||
retval = do_splice_direct(in.file, &pos, out.file, &out_pos,
|
||||
count, fl);
|
||||
file_end_write(out.file);
|
||||
} else {
|
||||
retval = splice_file_to_pipe(in.file, opipe, &pos, count, fl);
|
||||
}
|
||||
|
||||
if (retval > 0) {
|
||||
add_rchar(current, retval);
|
||||
|
|
|
@ -1002,7 +1002,7 @@ static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
|
|||
struct pipe_inode_info *opipe,
|
||||
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,
|
||||
loff_t *offset,
|
||||
size_t len, unsigned int flags)
|
||||
|
|
Загрузка…
Ссылка в новой задаче