struct shrink_control;
struct fs_context;
struct user_namespace;
+struct pipe_inode_info;
/*
* block_dev.c
*/
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);
{
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;
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);
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);
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)