Loading fs/internal.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -131,6 +131,12 @@ extern struct dentry *__d_alloc(struct super_block *, const struct qstr *); */ */ extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); /* * splice.c */ extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, loff_t *opos, size_t len, unsigned int flags); /* /* * pipe.c * pipe.c */ */ Loading fs/read_write.c +16 −8 Original line number Original line Diff line number Diff line Loading @@ -1064,6 +1064,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; loff_t pos; loff_t pos; loff_t out_pos; ssize_t retval; ssize_t retval; int fl; int fl; Loading @@ -1077,12 +1078,14 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, if (!(in.file->f_mode & FMODE_READ)) if (!(in.file->f_mode & FMODE_READ)) goto fput_in; goto fput_in; retval = -ESPIPE; retval = -ESPIPE; if (!ppos) if (!ppos) { ppos = &in.file->f_pos; pos = in.file->f_pos; else } else { pos = *ppos; if (!(in.file->f_mode & FMODE_PREAD)) if (!(in.file->f_mode & FMODE_PREAD)) goto fput_in; goto fput_in; retval = rw_verify_area(READ, in.file, ppos, count); } retval = rw_verify_area(READ, in.file, &pos, count); if (retval < 0) if (retval < 0) goto fput_in; goto fput_in; count = retval; count = retval; Loading @@ -1099,7 +1102,8 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, retval = -EINVAL; retval = -EINVAL; in_inode = file_inode(in.file); in_inode = file_inode(in.file); out_inode = file_inode(out.file); out_inode = file_inode(out.file); retval = rw_verify_area(WRITE, out.file, &out.file->f_pos, count); out_pos = out.file->f_pos; retval = rw_verify_area(WRITE, out.file, &out_pos, count); if (retval < 0) if (retval < 0) goto fput_out; goto fput_out; count = retval; count = retval; Loading @@ -1107,7 +1111,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, 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); pos = *ppos; if (unlikely(pos + count > max)) { if (unlikely(pos + count > max)) { retval = -EOVERFLOW; retval = -EOVERFLOW; if (pos >= max) if (pos >= max) Loading @@ -1126,18 +1129,23 @@ 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 retval = do_splice_direct(in.file, ppos, out.file, count, fl); retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl); if (retval > 0) { if (retval > 0) { add_rchar(current, retval); add_rchar(current, retval); add_wchar(current, retval); add_wchar(current, retval); fsnotify_access(in.file); fsnotify_access(in.file); fsnotify_modify(out.file); fsnotify_modify(out.file); out.file->f_pos = out_pos; if (ppos) *ppos = pos; else in.file->f_pos = pos; } } inc_syscr(current); inc_syscr(current); inc_syscw(current); inc_syscw(current); if (*ppos > max) if (pos > max) retval = -EOVERFLOW; retval = -EOVERFLOW; fput_out: fput_out: Loading fs/splice.c +18 −13 Original line number Original line Diff line number Diff line Loading @@ -1274,7 +1274,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, { { struct file *file = sd->u.file; struct file *file = sd->u.file; return do_splice_from(pipe, file, &file->f_pos, sd->total_len, return do_splice_from(pipe, file, sd->opos, sd->total_len, sd->flags); sd->flags); } } Loading @@ -1294,7 +1294,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, * * */ */ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, size_t len, unsigned int flags) loff_t *opos, size_t len, unsigned int flags) { { struct splice_desc sd = { struct splice_desc sd = { .len = len, .len = len, Loading @@ -1302,6 +1302,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, .flags = flags, .flags = flags, .pos = *ppos, .pos = *ppos, .u.file = out, .u.file = out, .opos = opos, }; }; long ret; long ret; Loading @@ -1325,7 +1326,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, { { struct pipe_inode_info *ipipe; struct pipe_inode_info *ipipe; struct pipe_inode_info *opipe; struct pipe_inode_info *opipe; loff_t offset, *off; loff_t offset; long ret; long ret; ipipe = get_pipe_info(in); ipipe = get_pipe_info(in); Loading Loading @@ -1356,13 +1357,15 @@ static long do_splice(struct file *in, loff_t __user *off_in, return -EINVAL; return -EINVAL; if (copy_from_user(&offset, off_out, sizeof(loff_t))) if (copy_from_user(&offset, off_out, sizeof(loff_t))) return -EFAULT; return -EFAULT; off = &offset; } else { } else offset = out->f_pos; off = &out->f_pos; } ret = do_splice_from(ipipe, out, off, len, flags); ret = do_splice_from(ipipe, out, &offset, len, flags); if (off_out && copy_to_user(off_out, off, sizeof(loff_t))) if (!off_out) out->f_pos = offset; else if (copy_to_user(off_out, &offset, sizeof(loff_t))) ret = -EFAULT; ret = -EFAULT; return ret; return ret; Loading @@ -1376,13 +1379,15 @@ static long do_splice(struct file *in, loff_t __user *off_in, return -EINVAL; return -EINVAL; if (copy_from_user(&offset, off_in, sizeof(loff_t))) if (copy_from_user(&offset, off_in, sizeof(loff_t))) return -EFAULT; return -EFAULT; off = &offset; } else { } else offset = in->f_pos; off = &in->f_pos; } ret = do_splice_to(in, off, opipe, len, flags); ret = do_splice_to(in, &offset, opipe, len, flags); if (off_in && copy_to_user(off_in, off, sizeof(loff_t))) if (!off_in) in->f_pos = offset; else if (copy_to_user(off_in, &offset, sizeof(loff_t))) ret = -EFAULT; ret = -EFAULT; return ret; return ret; Loading include/linux/fs.h +0 −2 Original line number Original line Diff line number Diff line Loading @@ -2414,8 +2414,6 @@ extern ssize_t generic_file_splice_write(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); struct file *, loff_t *, size_t, unsigned int); extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, loff_t *, size_t len, unsigned int flags); struct file *out, loff_t *, size_t len, unsigned int flags); extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, size_t len, unsigned int flags); extern void extern void file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); Loading include/linux/splice.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ struct splice_desc { void *data; /* cookie */ void *data; /* cookie */ } u; } u; loff_t pos; /* file position */ loff_t pos; /* file position */ loff_t *opos; /* sendfile: output position */ size_t num_spliced; /* number of bytes already spliced */ size_t num_spliced; /* number of bytes already spliced */ bool need_wakeup; /* need to wake up writer */ bool need_wakeup; /* need to wake up writer */ }; }; Loading Loading
fs/internal.h +6 −0 Original line number Original line Diff line number Diff line Loading @@ -131,6 +131,12 @@ extern struct dentry *__d_alloc(struct super_block *, const struct qstr *); */ */ extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); /* * splice.c */ extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, loff_t *opos, size_t len, unsigned int flags); /* /* * pipe.c * pipe.c */ */ Loading
fs/read_write.c +16 −8 Original line number Original line Diff line number Diff line Loading @@ -1064,6 +1064,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; loff_t pos; loff_t pos; loff_t out_pos; ssize_t retval; ssize_t retval; int fl; int fl; Loading @@ -1077,12 +1078,14 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, if (!(in.file->f_mode & FMODE_READ)) if (!(in.file->f_mode & FMODE_READ)) goto fput_in; goto fput_in; retval = -ESPIPE; retval = -ESPIPE; if (!ppos) if (!ppos) { ppos = &in.file->f_pos; pos = in.file->f_pos; else } else { pos = *ppos; if (!(in.file->f_mode & FMODE_PREAD)) if (!(in.file->f_mode & FMODE_PREAD)) goto fput_in; goto fput_in; retval = rw_verify_area(READ, in.file, ppos, count); } retval = rw_verify_area(READ, in.file, &pos, count); if (retval < 0) if (retval < 0) goto fput_in; goto fput_in; count = retval; count = retval; Loading @@ -1099,7 +1102,8 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, retval = -EINVAL; retval = -EINVAL; in_inode = file_inode(in.file); in_inode = file_inode(in.file); out_inode = file_inode(out.file); out_inode = file_inode(out.file); retval = rw_verify_area(WRITE, out.file, &out.file->f_pos, count); out_pos = out.file->f_pos; retval = rw_verify_area(WRITE, out.file, &out_pos, count); if (retval < 0) if (retval < 0) goto fput_out; goto fput_out; count = retval; count = retval; Loading @@ -1107,7 +1111,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, 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); pos = *ppos; if (unlikely(pos + count > max)) { if (unlikely(pos + count > max)) { retval = -EOVERFLOW; retval = -EOVERFLOW; if (pos >= max) if (pos >= max) Loading @@ -1126,18 +1129,23 @@ 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 retval = do_splice_direct(in.file, ppos, out.file, count, fl); retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl); if (retval > 0) { if (retval > 0) { add_rchar(current, retval); add_rchar(current, retval); add_wchar(current, retval); add_wchar(current, retval); fsnotify_access(in.file); fsnotify_access(in.file); fsnotify_modify(out.file); fsnotify_modify(out.file); out.file->f_pos = out_pos; if (ppos) *ppos = pos; else in.file->f_pos = pos; } } inc_syscr(current); inc_syscr(current); inc_syscw(current); inc_syscw(current); if (*ppos > max) if (pos > max) retval = -EOVERFLOW; retval = -EOVERFLOW; fput_out: fput_out: Loading
fs/splice.c +18 −13 Original line number Original line Diff line number Diff line Loading @@ -1274,7 +1274,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, { { struct file *file = sd->u.file; struct file *file = sd->u.file; return do_splice_from(pipe, file, &file->f_pos, sd->total_len, return do_splice_from(pipe, file, sd->opos, sd->total_len, sd->flags); sd->flags); } } Loading @@ -1294,7 +1294,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, * * */ */ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, size_t len, unsigned int flags) loff_t *opos, size_t len, unsigned int flags) { { struct splice_desc sd = { struct splice_desc sd = { .len = len, .len = len, Loading @@ -1302,6 +1302,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, .flags = flags, .flags = flags, .pos = *ppos, .pos = *ppos, .u.file = out, .u.file = out, .opos = opos, }; }; long ret; long ret; Loading @@ -1325,7 +1326,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, { { struct pipe_inode_info *ipipe; struct pipe_inode_info *ipipe; struct pipe_inode_info *opipe; struct pipe_inode_info *opipe; loff_t offset, *off; loff_t offset; long ret; long ret; ipipe = get_pipe_info(in); ipipe = get_pipe_info(in); Loading Loading @@ -1356,13 +1357,15 @@ static long do_splice(struct file *in, loff_t __user *off_in, return -EINVAL; return -EINVAL; if (copy_from_user(&offset, off_out, sizeof(loff_t))) if (copy_from_user(&offset, off_out, sizeof(loff_t))) return -EFAULT; return -EFAULT; off = &offset; } else { } else offset = out->f_pos; off = &out->f_pos; } ret = do_splice_from(ipipe, out, off, len, flags); ret = do_splice_from(ipipe, out, &offset, len, flags); if (off_out && copy_to_user(off_out, off, sizeof(loff_t))) if (!off_out) out->f_pos = offset; else if (copy_to_user(off_out, &offset, sizeof(loff_t))) ret = -EFAULT; ret = -EFAULT; return ret; return ret; Loading @@ -1376,13 +1379,15 @@ static long do_splice(struct file *in, loff_t __user *off_in, return -EINVAL; return -EINVAL; if (copy_from_user(&offset, off_in, sizeof(loff_t))) if (copy_from_user(&offset, off_in, sizeof(loff_t))) return -EFAULT; return -EFAULT; off = &offset; } else { } else offset = in->f_pos; off = &in->f_pos; } ret = do_splice_to(in, off, opipe, len, flags); ret = do_splice_to(in, &offset, opipe, len, flags); if (off_in && copy_to_user(off_in, off, sizeof(loff_t))) if (!off_in) in->f_pos = offset; else if (copy_to_user(off_in, &offset, sizeof(loff_t))) ret = -EFAULT; ret = -EFAULT; return ret; return ret; Loading
include/linux/fs.h +0 −2 Original line number Original line Diff line number Diff line Loading @@ -2414,8 +2414,6 @@ extern ssize_t generic_file_splice_write(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); struct file *, loff_t *, size_t, unsigned int); extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, loff_t *, size_t len, unsigned int flags); struct file *out, loff_t *, size_t len, unsigned int flags); extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, size_t len, unsigned int flags); extern void extern void file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); Loading
include/linux/splice.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ struct splice_desc { void *data; /* cookie */ void *data; /* cookie */ } u; } u; loff_t pos; /* file position */ loff_t pos; /* file position */ loff_t *opos; /* sendfile: output position */ size_t num_spliced; /* number of bytes already spliced */ size_t num_spliced; /* number of bytes already spliced */ bool need_wakeup; /* need to wake up writer */ bool need_wakeup; /* need to wake up writer */ }; }; Loading