Commit 9ca68662 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'tee' of git://brick.kernel.dk/data/git/linux-2.6-block

* 'tee' of git://brick.kernel.dk/data/git/linux-2.6-block:
  [PATCH] splice: add support for sys_tee()
  [PATCH] splice: pass offset around for ->splice_read() and ->splice_write()
parents e57a5059 70524490
...@@ -314,3 +314,4 @@ ENTRY(sys_call_table) ...@@ -314,3 +314,4 @@ ENTRY(sys_call_table)
.long sys_get_robust_list .long sys_get_robust_list
.long sys_splice .long sys_splice
.long sys_sync_file_range .long sys_sync_file_range
.long sys_tee /* 315 */
...@@ -1609,5 +1609,6 @@ sys_call_table: ...@@ -1609,5 +1609,6 @@ sys_call_table:
data8 sys_set_robust_list data8 sys_set_robust_list
data8 sys_get_robust_list data8 sys_get_robust_list
data8 sys_sync_file_range // 1300 data8 sys_sync_file_range // 1300
data8 sys_tee
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
...@@ -323,3 +323,4 @@ COMPAT_SYS(pselect6) ...@@ -323,3 +323,4 @@ COMPAT_SYS(pselect6)
COMPAT_SYS(ppoll) COMPAT_SYS(ppoll)
SYSCALL(unshare) SYSCALL(unshare)
SYSCALL(splice) SYSCALL(splice)
SYSCALL(tee)
...@@ -131,12 +131,19 @@ static int anon_pipe_buf_steal(struct pipe_inode_info *pipe, ...@@ -131,12 +131,19 @@ static int anon_pipe_buf_steal(struct pipe_inode_info *pipe,
return 0; return 0;
} }
static void anon_pipe_buf_get(struct pipe_inode_info *info,
struct pipe_buffer *buf)
{
page_cache_get(buf->page);
}
static struct pipe_buf_operations anon_pipe_buf_ops = { static struct pipe_buf_operations anon_pipe_buf_ops = {
.can_merge = 1, .can_merge = 1,
.map = anon_pipe_buf_map, .map = anon_pipe_buf_map,
.unmap = anon_pipe_buf_unmap, .unmap = anon_pipe_buf_unmap,
.release = anon_pipe_buf_release, .release = anon_pipe_buf_release,
.steal = anon_pipe_buf_steal, .steal = anon_pipe_buf_steal,
.get = anon_pipe_buf_get,
}; };
static ssize_t static ssize_t
......
This diff is collapsed.
...@@ -252,6 +252,7 @@ xfs_file_sendfile_invis( ...@@ -252,6 +252,7 @@ xfs_file_sendfile_invis(
STATIC ssize_t STATIC ssize_t
xfs_file_splice_read( xfs_file_splice_read(
struct file *infilp, struct file *infilp,
loff_t *ppos,
struct pipe_inode_info *pipe, struct pipe_inode_info *pipe,
size_t len, size_t len,
unsigned int flags) unsigned int flags)
...@@ -259,13 +260,14 @@ xfs_file_splice_read( ...@@ -259,13 +260,14 @@ xfs_file_splice_read(
vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode);
ssize_t rval; ssize_t rval;
VOP_SPLICE_READ(vp, infilp, pipe, len, flags, 0, NULL, rval); VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, 0, NULL, rval);
return rval; return rval;
} }
STATIC ssize_t STATIC ssize_t
xfs_file_splice_read_invis( xfs_file_splice_read_invis(
struct file *infilp, struct file *infilp,
loff_t *ppos,
struct pipe_inode_info *pipe, struct pipe_inode_info *pipe,
size_t len, size_t len,
unsigned int flags) unsigned int flags)
...@@ -273,7 +275,7 @@ xfs_file_splice_read_invis( ...@@ -273,7 +275,7 @@ xfs_file_splice_read_invis(
vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode);
ssize_t rval; ssize_t rval;
VOP_SPLICE_READ(vp, infilp, pipe, len, flags, IO_INVIS, NULL, rval); VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, IO_INVIS, NULL, rval);
return rval; return rval;
} }
...@@ -281,13 +283,14 @@ STATIC ssize_t ...@@ -281,13 +283,14 @@ STATIC ssize_t
xfs_file_splice_write( xfs_file_splice_write(
struct pipe_inode_info *pipe, struct pipe_inode_info *pipe,
struct file *outfilp, struct file *outfilp,
loff_t *ppos,
size_t len, size_t len,
unsigned int flags) unsigned int flags)
{ {
vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode);
ssize_t rval; ssize_t rval;
VOP_SPLICE_WRITE(vp, pipe, outfilp, len, flags, 0, NULL, rval); VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, 0, NULL, rval);
return rval; return rval;
} }
...@@ -295,13 +298,14 @@ STATIC ssize_t ...@@ -295,13 +298,14 @@ STATIC ssize_t
xfs_file_splice_write_invis( xfs_file_splice_write_invis(
struct pipe_inode_info *pipe, struct pipe_inode_info *pipe,
struct file *outfilp, struct file *outfilp,
loff_t *ppos,
size_t len, size_t len,
unsigned int flags) unsigned int flags)
{ {
vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode);
ssize_t rval; ssize_t rval;
VOP_SPLICE_WRITE(vp, pipe, outfilp, len, flags, IO_INVIS, NULL, rval); VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, IO_INVIS, NULL, rval);
return rval; return rval;
} }
......
...@@ -338,6 +338,7 @@ ssize_t ...@@ -338,6 +338,7 @@ ssize_t
xfs_splice_read( xfs_splice_read(
bhv_desc_t *bdp, bhv_desc_t *bdp,
struct file *infilp, struct file *infilp,
loff_t *ppos,
struct pipe_inode_info *pipe, struct pipe_inode_info *pipe,
size_t count, size_t count,
int flags, int flags,
...@@ -360,7 +361,7 @@ xfs_splice_read( ...@@ -360,7 +361,7 @@ xfs_splice_read(
int error; int error;
error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
infilp->f_pos, count, *ppos, count,
FILP_DELAY_FLAG(infilp), &locktype); FILP_DELAY_FLAG(infilp), &locktype);
if (error) { if (error) {
xfs_iunlock(ip, XFS_IOLOCK_SHARED); xfs_iunlock(ip, XFS_IOLOCK_SHARED);
...@@ -368,8 +369,8 @@ xfs_splice_read( ...@@ -368,8 +369,8 @@ xfs_splice_read(
} }
} }
xfs_rw_enter_trace(XFS_SPLICE_READ_ENTER, &ip->i_iocore, xfs_rw_enter_trace(XFS_SPLICE_READ_ENTER, &ip->i_iocore,
pipe, count, infilp->f_pos, ioflags); pipe, count, *ppos, ioflags);
ret = generic_file_splice_read(infilp, pipe, count, flags); ret = generic_file_splice_read(infilp, ppos, pipe, count, flags);
if (ret > 0) if (ret > 0)
XFS_STATS_ADD(xs_read_bytes, ret); XFS_STATS_ADD(xs_read_bytes, ret);
...@@ -382,6 +383,7 @@ xfs_splice_write( ...@@ -382,6 +383,7 @@ xfs_splice_write(
bhv_desc_t *bdp, bhv_desc_t *bdp,
struct pipe_inode_info *pipe, struct pipe_inode_info *pipe,
struct file *outfilp, struct file *outfilp,
loff_t *ppos,
size_t count, size_t count,
int flags, int flags,
int ioflags, int ioflags,
...@@ -403,7 +405,7 @@ xfs_splice_write( ...@@ -403,7 +405,7 @@ xfs_splice_write(
int error; int error;
error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp), error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp),
outfilp->f_pos, count, *ppos, count,
FILP_DELAY_FLAG(outfilp), &locktype); FILP_DELAY_FLAG(outfilp), &locktype);
if (error) { if (error) {
xfs_iunlock(ip, XFS_IOLOCK_EXCL); xfs_iunlock(ip, XFS_IOLOCK_EXCL);
...@@ -411,8 +413,8 @@ xfs_splice_write( ...@@ -411,8 +413,8 @@ xfs_splice_write(
} }
} }
xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore, xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore,
pipe, count, outfilp->f_pos, ioflags); pipe, count, *ppos, ioflags);
ret = generic_file_splice_write(pipe, outfilp, count, flags); ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags);
if (ret > 0) if (ret > 0)
XFS_STATS_ADD(xs_write_bytes, ret); XFS_STATS_ADD(xs_write_bytes, ret);
......
...@@ -93,11 +93,11 @@ extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *, ...@@ -93,11 +93,11 @@ extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *,
extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *, extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *,
loff_t *, int, size_t, read_actor_t, loff_t *, int, size_t, read_actor_t,
void *, struct cred *); void *, struct cred *);
extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, loff_t *,
struct pipe_inode_info *, size_t, int, int, struct pipe_inode_info *, size_t, int, int,
struct cred *); struct cred *);
extern ssize_t xfs_splice_write(struct bhv_desc *, struct pipe_inode_info *, extern ssize_t xfs_splice_write(struct bhv_desc *, struct pipe_inode_info *,
struct file *, size_t, int, int, struct file *, loff_t *, size_t, int, int,
struct cred *); struct cred *);
#endif /* __XFS_LRW_H__ */ #endif /* __XFS_LRW_H__ */
...@@ -173,11 +173,11 @@ typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *, ...@@ -173,11 +173,11 @@ typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *,
typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *, typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *,
loff_t *, int, size_t, read_actor_t, loff_t *, int, size_t, read_actor_t,
void *, struct cred *); void *, struct cred *);
typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, loff_t *,
struct pipe_inode_info *, size_t, int, int, struct pipe_inode_info *, size_t, int, int,
struct cred *); struct cred *);
typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *, typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *,
struct file *, size_t, int, int, struct file *, loff_t *, size_t, int, int,
struct cred *); struct cred *);
typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
int, unsigned int, void __user *); int, unsigned int, void __user *);
...@@ -284,10 +284,10 @@ typedef struct vnodeops { ...@@ -284,10 +284,10 @@ typedef struct vnodeops {
rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr) rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
#define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \ #define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \
rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr) rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr)
#define VOP_SPLICE_READ(vp,f,pipe,cnt,fl,iofl,cr,rv) \ #define VOP_SPLICE_READ(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \
rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,pipe,cnt,fl,iofl,cr) rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
#define VOP_SPLICE_WRITE(vp,f,pipe,cnt,fl,iofl,cr,rv) \ #define VOP_SPLICE_WRITE(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \
rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,pipe,cnt,fl,iofl,cr) rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \ #define VOP_BMAP(vp,of,sz,rw,b,n,rv) \
rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n) rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n)
#define VOP_OPEN(vp, cr, rv) \ #define VOP_OPEN(vp, cr, rv) \
......
...@@ -320,8 +320,9 @@ ...@@ -320,8 +320,9 @@
#define __NR_get_robust_list 312 #define __NR_get_robust_list 312
#define __NR_splice 313 #define __NR_splice 313
#define __NR_sync_file_range 314 #define __NR_sync_file_range 314
#define __NR_tee 315
#define NR_syscalls 315 #define NR_syscalls 316
/* /*
* user-visible error numbers are in the range -1 - -128: see * user-visible error numbers are in the range -1 - -128: see
......
...@@ -289,12 +289,13 @@ ...@@ -289,12 +289,13 @@
#define __NR_set_robust_list 1298 #define __NR_set_robust_list 1298
#define __NR_get_robust_list 1299 #define __NR_get_robust_list 1299
#define __NR_sync_file_range 1300 #define __NR_sync_file_range 1300
#define __NR_tee 1301
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/config.h> #include <linux/config.h>
#define NR_syscalls 277 /* length of syscall table */ #define NR_syscalls 278 /* length of syscall table */
#define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGACTION
......
...@@ -302,8 +302,9 @@ ...@@ -302,8 +302,9 @@
#define __NR_ppoll 281 #define __NR_ppoll 281
#define __NR_unshare 282 #define __NR_unshare 282
#define __NR_splice 283 #define __NR_splice 283
#define __NR_tee 284
#define __NR_syscalls 284 #define __NR_syscalls 285
#ifdef __KERNEL__ #ifdef __KERNEL__
#define __NR__exit __NR_exit #define __NR__exit __NR_exit
......
...@@ -611,8 +611,10 @@ __SYSCALL(__NR_set_robust_list, sys_set_robust_list) ...@@ -611,8 +611,10 @@ __SYSCALL(__NR_set_robust_list, sys_set_robust_list)
__SYSCALL(__NR_get_robust_list, sys_get_robust_list) __SYSCALL(__NR_get_robust_list, sys_get_robust_list)
#define __NR_splice 275 #define __NR_splice 275
__SYSCALL(__NR_splice, sys_splice) __SYSCALL(__NR_splice, sys_splice)
#define __NR_tee 276
__SYSCALL(__NR_tee, sys_tee)
#define __NR_syscall_max __NR_splice #define __NR_syscall_max __NR_tee
#ifndef __NO_STUBS #ifndef __NO_STUBS
......
...@@ -1039,8 +1039,8 @@ struct file_operations { ...@@ -1039,8 +1039,8 @@ struct file_operations {
int (*check_flags)(int); int (*check_flags)(int);
int (*dir_notify)(struct file *filp, unsigned long arg); int (*dir_notify)(struct file *filp, unsigned long arg);
int (*flock) (struct file *, int, struct file_lock *); int (*flock) (struct file *, int, struct file_lock *);
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
}; };
struct inode_operations { struct inode_operations {
...@@ -1613,13 +1613,13 @@ extern void do_generic_mapping_read(struct address_space *mapping, ...@@ -1613,13 +1613,13 @@ extern void do_generic_mapping_read(struct address_space *mapping,
loff_t *, read_descriptor_t *, read_actor_t); loff_t *, read_descriptor_t *, read_actor_t);
/* fs/splice.c */ /* fs/splice.c */
extern ssize_t generic_file_splice_read(struct file *, extern ssize_t generic_file_splice_read(struct file *, loff_t *,
struct pipe_inode_info *, size_t, unsigned int); struct pipe_inode_info *, size_t, unsigned int);
extern ssize_t generic_file_splice_write(struct pipe_inode_info *, extern ssize_t generic_file_splice_write(struct pipe_inode_info *,
struct file *, 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, 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, struct file *out, extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
size_t len, unsigned int flags); size_t len, unsigned int flags);
extern void extern void
......
...@@ -21,6 +21,7 @@ struct pipe_buf_operations { ...@@ -21,6 +21,7 @@ struct pipe_buf_operations {
void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *); void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *);
void (*release)(struct pipe_inode_info *, struct pipe_buffer *); void (*release)(struct pipe_inode_info *, struct pipe_buffer *);
int (*steal)(struct pipe_inode_info *, struct pipe_buffer *); int (*steal)(struct pipe_inode_info *, struct pipe_buffer *);
void (*get)(struct pipe_inode_info *, struct pipe_buffer *);
}; };
struct pipe_inode_info { struct pipe_inode_info {
......
...@@ -574,6 +574,8 @@ asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, ...@@ -574,6 +574,8 @@ asmlinkage long sys_splice(int fd_in, loff_t __user *off_in,
int fd_out, loff_t __user *off_out, int fd_out, loff_t __user *off_out,
size_t len, unsigned int flags); size_t len, unsigned int flags);
asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags);
asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
unsigned int flags); unsigned int flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment