mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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
					
				
					 3 changed files with 23 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue