Skip to content

Commit b964bf5

Browse files
author
Al Viro
committed
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>
1 parent faa97c4 commit b964bf5

File tree

3 files changed

+23
-7
lines changed

3 files changed

+23
-7
lines changed

fs/internal.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct mount;
1515
struct shrink_control;
1616
struct fs_context;
1717
struct user_namespace;
18+
struct pipe_inode_info;
1819

1920
/*
2021
* block_dev.c
@@ -193,3 +194,11 @@ int sb_init_dio_done_wq(struct super_block *sb);
193194
*/
194195
int do_statx(int dfd, const char __user *filename, unsigned flags,
195196
unsigned int mask, struct statx __user *buffer);
197+
198+
/*
199+
* fs/splice.c:
200+
*/
201+
long splice_file_to_pipe(struct file *in,
202+
struct pipe_inode_info *opipe,
203+
loff_t *offset,
204+
size_t len, unsigned int flags);

fs/read_write.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
11881188
{
11891189
struct fd in, out;
11901190
struct inode *in_inode, *out_inode;
1191+
struct pipe_inode_info *opipe;
11911192
loff_t pos;
11921193
loff_t out_pos;
11931194
ssize_t retval;
@@ -1228,9 +1229,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
12281229
in_inode = file_inode(in.file);
12291230
out_inode = file_inode(out.file);
12301231
out_pos = out.file->f_pos;
1231-
retval = rw_verify_area(WRITE, out.file, &out_pos, count);
1232-
if (retval < 0)
1233-
goto fput_out;
12341232

12351233
if (!max)
12361234
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,
12531251
if (in.file->f_flags & O_NONBLOCK)
12541252
fl = SPLICE_F_NONBLOCK;
12551253
#endif
1256-
file_start_write(out.file);
1257-
retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl);
1258-
file_end_write(out.file);
1254+
opipe = get_pipe_info(out.file, true);
1255+
if (!opipe) {
1256+
retval = rw_verify_area(WRITE, out.file, &out_pos, count);
1257+
if (retval < 0)
1258+
goto fput_out;
1259+
file_start_write(out.file);
1260+
retval = do_splice_direct(in.file, &pos, out.file, &out_pos,
1261+
count, fl);
1262+
file_end_write(out.file);
1263+
} else {
1264+
retval = splice_file_to_pipe(in.file, opipe, &pos, count, fl);
1265+
}
12591266

12601267
if (retval > 0) {
12611268
add_rchar(current, retval);

fs/splice.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,7 @@ static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
10021002
struct pipe_inode_info *opipe,
10031003
size_t len, unsigned int flags);
10041004

1005-
static long splice_file_to_pipe(struct file *in,
1005+
long splice_file_to_pipe(struct file *in,
10061006
struct pipe_inode_info *opipe,
10071007
loff_t *offset,
10081008
size_t len, unsigned int flags)

0 commit comments

Comments
 (0)