aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-10 16:51:06 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-10 16:51:06 -0400
commit01370f0603f8435d415a19f7e62d1bab826c3589 (patch)
treed3ce7c36c6f9e33bd1d8328ef58f2fca41a18cb3 /fs
parent5cbc39a726eafa1198c18adb3cf56ccee371dba1 (diff)
parent0845718dafea3e16041d270c256e8516acf4e13d (diff)
Merge branch 'splice-2.6.23' of git://git.kernel.dk/data/git/linux-2.6-block
* 'splice-2.6.23' of git://git.kernel.dk/data/git/linux-2.6-block: pipe: add documentation and comments pipe: change the ->pin() operation to ->confirm() Remove remnants of sendfile() xip sendfile removal splice: completely document external interface with kerneldoc sendfile: remove bad_sendfile() from bad_file_ops shmem: convert to using splice instead of sendfile() relay: use splice_to_pipe() instead of open-coding the pipe loop pipe: allow passing around of ops private pointer splice: divorce the splice structure/function definitions from the pipe header splice: relay support sendfile: convert nfsd to splice_direct_to_actor() sendfile: convert nfs to using splice_read() loop: convert to using splice_direct_to_actor() instead of sendfile() splice: add void cookie to the actor data sendfile: kill generic_file_sendfile() sendfile: remove .sendfile from filesystems that use generic_file_sendfile() sys_sendfile: switch to using ->splice_read, if available vmsplice: add vmsplice-to-user support splice: abstract out actor data
Diffstat (limited to 'fs')
-rw-r--r--fs/adfs/file.c2
-rw-r--r--fs/affs/file.c2
-rw-r--r--fs/afs/file.c2
-rw-r--r--fs/bad_inode.c7
-rw-r--r--fs/bfs/file.c2
-rw-r--r--fs/block_dev.c1
-rw-r--r--fs/cifs/cifsfs.c8
-rw-r--r--fs/coda/file.c11
-rw-r--r--fs/ecryptfs/file.c15
-rw-r--r--fs/ext2/file.c2
-rw-r--r--fs/ext3/file.c1
-rw-r--r--fs/ext4/file.c1
-rw-r--r--fs/fat/file.c2
-rw-r--r--fs/fuse/file.c4
-rw-r--r--fs/gfs2/ops_file.c1
-rw-r--r--fs/hfs/inode.c2
-rw-r--r--fs/hfsplus/inode.c2
-rw-r--r--fs/hostfs/hostfs_kern.c2
-rw-r--r--fs/hpfs/file.c2
-rw-r--r--fs/jffs2/file.c2
-rw-r--r--fs/jfs/file.c1
-rw-r--r--fs/minix/file.c2
-rw-r--r--fs/nfs/file.c15
-rw-r--r--fs/nfsd/vfs.c47
-rw-r--r--fs/ntfs/file.c2
-rw-r--r--fs/ocfs2/file.c18
-rw-r--r--fs/pipe.c70
-rw-r--r--fs/qnx4/file.c2
-rw-r--r--fs/ramfs/file-mmu.c2
-rw-r--r--fs/ramfs/file-nommu.c2
-rw-r--r--fs/read_write.c20
-rw-r--r--fs/reiserfs/file.c1
-rw-r--r--fs/smbfs/file.c9
-rw-r--r--fs/splice.c413
-rw-r--r--fs/sysv/file.c2
-rw-r--r--fs/udf/file.c2
-rw-r--r--fs/ufs/file.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c26
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c44
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h3
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h6
-rw-r--r--fs/xfs/xfs_vnodeops.c3
43 files changed, 488 insertions, 276 deletions
diff --git a/fs/adfs/file.c b/fs/adfs/file.c
index f544a2855923..36e381c6a99a 100644
--- a/fs/adfs/file.c
+++ b/fs/adfs/file.c
@@ -33,7 +33,7 @@ const struct file_operations adfs_file_operations = {
33 .fsync = file_fsync, 33 .fsync = file_fsync,
34 .write = do_sync_write, 34 .write = do_sync_write,
35 .aio_write = generic_file_aio_write, 35 .aio_write = generic_file_aio_write,
36 .sendfile = generic_file_sendfile, 36 .splice_read = generic_file_splice_read,
37}; 37};
38 38
39const struct inode_operations adfs_file_inode_operations = { 39const struct inode_operations adfs_file_inode_operations = {
diff --git a/fs/affs/file.c b/fs/affs/file.c
index c8796906f584..c314a35f0918 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -35,7 +35,7 @@ const struct file_operations affs_file_operations = {
35 .open = affs_file_open, 35 .open = affs_file_open,
36 .release = affs_file_release, 36 .release = affs_file_release,
37 .fsync = file_fsync, 37 .fsync = file_fsync,
38 .sendfile = generic_file_sendfile, 38 .splice_read = generic_file_splice_read,
39}; 39};
40 40
41const struct inode_operations affs_file_inode_operations = { 41const struct inode_operations affs_file_inode_operations = {
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 9c0e721d9fc2..aede7eb66dd4 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -32,7 +32,7 @@ const struct file_operations afs_file_operations = {
32 .aio_read = generic_file_aio_read, 32 .aio_read = generic_file_aio_read,
33 .aio_write = afs_file_write, 33 .aio_write = afs_file_write,
34 .mmap = generic_file_readonly_mmap, 34 .mmap = generic_file_readonly_mmap,
35 .sendfile = generic_file_sendfile, 35 .splice_read = generic_file_splice_read,
36 .fsync = afs_fsync, 36 .fsync = afs_fsync,
37}; 37};
38 38
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index 329ee473eede..521ff7caadbd 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -114,12 +114,6 @@ static int bad_file_lock(struct file *file, int cmd, struct file_lock *fl)
114 return -EIO; 114 return -EIO;
115} 115}
116 116
117static ssize_t bad_file_sendfile(struct file *in_file, loff_t *ppos,
118 size_t count, read_actor_t actor, void *target)
119{
120 return -EIO;
121}
122
123static ssize_t bad_file_sendpage(struct file *file, struct page *page, 117static ssize_t bad_file_sendpage(struct file *file, struct page *page,
124 int off, size_t len, loff_t *pos, int more) 118 int off, size_t len, loff_t *pos, int more)
125{ 119{
@@ -182,7 +176,6 @@ static const struct file_operations bad_file_ops =
182 .aio_fsync = bad_file_aio_fsync, 176 .aio_fsync = bad_file_aio_fsync,
183 .fasync = bad_file_fasync, 177 .fasync = bad_file_fasync,
184 .lock = bad_file_lock, 178 .lock = bad_file_lock,
185 .sendfile = bad_file_sendfile,
186 .sendpage = bad_file_sendpage, 179 .sendpage = bad_file_sendpage,
187 .get_unmapped_area = bad_file_get_unmapped_area, 180 .get_unmapped_area = bad_file_get_unmapped_area,
188 .check_flags = bad_file_check_flags, 181 .check_flags = bad_file_check_flags,
diff --git a/fs/bfs/file.c b/fs/bfs/file.c
index ef4d1fa04e65..24310e9ee05a 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -24,7 +24,7 @@ const struct file_operations bfs_file_operations = {
24 .write = do_sync_write, 24 .write = do_sync_write,
25 .aio_write = generic_file_aio_write, 25 .aio_write = generic_file_aio_write,
26 .mmap = generic_file_mmap, 26 .mmap = generic_file_mmap,
27 .sendfile = generic_file_sendfile, 27 .splice_read = generic_file_splice_read,
28}; 28};
29 29
30static int bfs_move_block(unsigned long from, unsigned long to, struct super_block *sb) 30static int bfs_move_block(unsigned long from, unsigned long to, struct super_block *sb)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index ea1480a16f51..b3e9bfa748cf 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1346,7 +1346,6 @@ const struct file_operations def_blk_fops = {
1346#ifdef CONFIG_COMPAT 1346#ifdef CONFIG_COMPAT
1347 .compat_ioctl = compat_blkdev_ioctl, 1347 .compat_ioctl = compat_blkdev_ioctl,
1348#endif 1348#endif
1349 .sendfile = generic_file_sendfile,
1350 .splice_read = generic_file_splice_read, 1349 .splice_read = generic_file_splice_read,
1351 .splice_write = generic_file_splice_write, 1350 .splice_write = generic_file_splice_write,
1352}; 1351};
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 7c04752b76cb..8b0cbf4a4ad0 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -616,7 +616,7 @@ const struct file_operations cifs_file_ops = {
616 .fsync = cifs_fsync, 616 .fsync = cifs_fsync,
617 .flush = cifs_flush, 617 .flush = cifs_flush,
618 .mmap = cifs_file_mmap, 618 .mmap = cifs_file_mmap,
619 .sendfile = generic_file_sendfile, 619 .splice_read = generic_file_splice_read,
620 .llseek = cifs_llseek, 620 .llseek = cifs_llseek,
621#ifdef CONFIG_CIFS_POSIX 621#ifdef CONFIG_CIFS_POSIX
622 .ioctl = cifs_ioctl, 622 .ioctl = cifs_ioctl,
@@ -637,7 +637,7 @@ const struct file_operations cifs_file_direct_ops = {
637 .lock = cifs_lock, 637 .lock = cifs_lock,
638 .fsync = cifs_fsync, 638 .fsync = cifs_fsync,
639 .flush = cifs_flush, 639 .flush = cifs_flush,
640 .sendfile = generic_file_sendfile, /* BB removeme BB */ 640 .splice_read = generic_file_splice_read,
641#ifdef CONFIG_CIFS_POSIX 641#ifdef CONFIG_CIFS_POSIX
642 .ioctl = cifs_ioctl, 642 .ioctl = cifs_ioctl,
643#endif /* CONFIG_CIFS_POSIX */ 643#endif /* CONFIG_CIFS_POSIX */
@@ -656,7 +656,7 @@ const struct file_operations cifs_file_nobrl_ops = {
656 .fsync = cifs_fsync, 656 .fsync = cifs_fsync,
657 .flush = cifs_flush, 657 .flush = cifs_flush,
658 .mmap = cifs_file_mmap, 658 .mmap = cifs_file_mmap,
659 .sendfile = generic_file_sendfile, 659 .splice_read = generic_file_splice_read,
660 .llseek = cifs_llseek, 660 .llseek = cifs_llseek,
661#ifdef CONFIG_CIFS_POSIX 661#ifdef CONFIG_CIFS_POSIX
662 .ioctl = cifs_ioctl, 662 .ioctl = cifs_ioctl,
@@ -676,7 +676,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
676 .release = cifs_close, 676 .release = cifs_close,
677 .fsync = cifs_fsync, 677 .fsync = cifs_fsync,
678 .flush = cifs_flush, 678 .flush = cifs_flush,
679 .sendfile = generic_file_sendfile, /* BB removeme BB */ 679 .splice_read = generic_file_splice_read,
680#ifdef CONFIG_CIFS_POSIX 680#ifdef CONFIG_CIFS_POSIX
681 .ioctl = cifs_ioctl, 681 .ioctl = cifs_ioctl,
682#endif /* CONFIG_CIFS_POSIX */ 682#endif /* CONFIG_CIFS_POSIX */
diff --git a/fs/coda/file.c b/fs/coda/file.c
index 5ef2b609ec7d..99dbe866816d 100644
--- a/fs/coda/file.c
+++ b/fs/coda/file.c
@@ -47,8 +47,9 @@ coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *p
47} 47}
48 48
49static ssize_t 49static ssize_t
50coda_file_sendfile(struct file *coda_file, loff_t *ppos, size_t count, 50coda_file_splice_read(struct file *coda_file, loff_t *ppos,
51 read_actor_t actor, void *target) 51 struct pipe_inode_info *pipe, size_t count,
52 unsigned int flags)
52{ 53{
53 struct coda_file_info *cfi; 54 struct coda_file_info *cfi;
54 struct file *host_file; 55 struct file *host_file;
@@ -57,10 +58,10 @@ coda_file_sendfile(struct file *coda_file, loff_t *ppos, size_t count,
57 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); 58 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
58 host_file = cfi->cfi_container; 59 host_file = cfi->cfi_container;
59 60
60 if (!host_file->f_op || !host_file->f_op->sendfile) 61 if (!host_file->f_op || !host_file->f_op->splice_read)
61 return -EINVAL; 62 return -EINVAL;
62 63
63 return host_file->f_op->sendfile(host_file, ppos, count, actor, target); 64 return host_file->f_op->splice_read(host_file, ppos, pipe, count,flags);
64} 65}
65 66
66static ssize_t 67static ssize_t
@@ -295,6 +296,6 @@ const struct file_operations coda_file_operations = {
295 .flush = coda_flush, 296 .flush = coda_flush,
296 .release = coda_release, 297 .release = coda_release,
297 .fsync = coda_fsync, 298 .fsync = coda_fsync,
298 .sendfile = coda_file_sendfile, 299 .splice_read = coda_file_splice_read,
299}; 300};
300 301
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 59288d817078..94f456fe4d9b 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -338,16 +338,17 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag)
338 return rc; 338 return rc;
339} 339}
340 340
341static ssize_t ecryptfs_sendfile(struct file *file, loff_t * ppos, 341static ssize_t ecryptfs_splice_read(struct file *file, loff_t * ppos,
342 size_t count, read_actor_t actor, void *target) 342 struct pipe_inode_info *pipe, size_t count,
343 unsigned int flags)
343{ 344{
344 struct file *lower_file = NULL; 345 struct file *lower_file = NULL;
345 int rc = -EINVAL; 346 int rc = -EINVAL;
346 347
347 lower_file = ecryptfs_file_to_lower(file); 348 lower_file = ecryptfs_file_to_lower(file);
348 if (lower_file->f_op && lower_file->f_op->sendfile) 349 if (lower_file->f_op && lower_file->f_op->splice_read)
349 rc = lower_file->f_op->sendfile(lower_file, ppos, count, 350 rc = lower_file->f_op->splice_read(lower_file, ppos, pipe,
350 actor, target); 351 count, flags);
351 352
352 return rc; 353 return rc;
353} 354}
@@ -364,7 +365,7 @@ const struct file_operations ecryptfs_dir_fops = {
364 .release = ecryptfs_release, 365 .release = ecryptfs_release,
365 .fsync = ecryptfs_fsync, 366 .fsync = ecryptfs_fsync,
366 .fasync = ecryptfs_fasync, 367 .fasync = ecryptfs_fasync,
367 .sendfile = ecryptfs_sendfile, 368 .splice_read = ecryptfs_splice_read,
368}; 369};
369 370
370const struct file_operations ecryptfs_main_fops = { 371const struct file_operations ecryptfs_main_fops = {
@@ -381,7 +382,7 @@ const struct file_operations ecryptfs_main_fops = {
381 .release = ecryptfs_release, 382 .release = ecryptfs_release,
382 .fsync = ecryptfs_fsync, 383 .fsync = ecryptfs_fsync,
383 .fasync = ecryptfs_fasync, 384 .fasync = ecryptfs_fasync,
384 .sendfile = ecryptfs_sendfile, 385 .splice_read = ecryptfs_splice_read,
385}; 386};
386 387
387static int 388static int
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 566d4e2d3852..04afeecaaef3 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -53,7 +53,6 @@ const struct file_operations ext2_file_operations = {
53 .open = generic_file_open, 53 .open = generic_file_open,
54 .release = ext2_release_file, 54 .release = ext2_release_file,
55 .fsync = ext2_sync_file, 55 .fsync = ext2_sync_file,
56 .sendfile = generic_file_sendfile,
57 .splice_read = generic_file_splice_read, 56 .splice_read = generic_file_splice_read,
58 .splice_write = generic_file_splice_write, 57 .splice_write = generic_file_splice_write,
59}; 58};
@@ -71,7 +70,6 @@ const struct file_operations ext2_xip_file_operations = {
71 .open = generic_file_open, 70 .open = generic_file_open,
72 .release = ext2_release_file, 71 .release = ext2_release_file,
73 .fsync = ext2_sync_file, 72 .fsync = ext2_sync_file,
74 .sendfile = xip_file_sendfile,
75}; 73};
76#endif 74#endif
77 75
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 1e6f13864536..acc4913d3019 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -120,7 +120,6 @@ const struct file_operations ext3_file_operations = {
120 .open = generic_file_open, 120 .open = generic_file_open,
121 .release = ext3_release_file, 121 .release = ext3_release_file,
122 .fsync = ext3_sync_file, 122 .fsync = ext3_sync_file,
123 .sendfile = generic_file_sendfile,
124 .splice_read = generic_file_splice_read, 123 .splice_read = generic_file_splice_read,
125 .splice_write = generic_file_splice_write, 124 .splice_write = generic_file_splice_write,
126}; 125};
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 3c6c1fd2be90..d4c8186aed64 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -120,7 +120,6 @@ const struct file_operations ext4_file_operations = {
120 .open = generic_file_open, 120 .open = generic_file_open,
121 .release = ext4_release_file, 121 .release = ext4_release_file,
122 .fsync = ext4_sync_file, 122 .fsync = ext4_sync_file,
123 .sendfile = generic_file_sendfile,
124 .splice_read = generic_file_splice_read, 123 .splice_read = generic_file_splice_read,
125 .splice_write = generic_file_splice_write, 124 .splice_write = generic_file_splice_write,
126}; 125};
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 55d3c7461c5b..69a83b59dce8 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -134,7 +134,7 @@ const struct file_operations fat_file_operations = {
134 .release = fat_file_release, 134 .release = fat_file_release,
135 .ioctl = fat_generic_ioctl, 135 .ioctl = fat_generic_ioctl,
136 .fsync = file_fsync, 136 .fsync = file_fsync,
137 .sendfile = generic_file_sendfile, 137 .splice_read = generic_file_splice_read,
138}; 138};
139 139
140static int fat_cont_expand(struct inode *inode, loff_t size) 140static int fat_cont_expand(struct inode *inode, loff_t size)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index adf7995232b8..f79de7c8cdfa 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -802,7 +802,7 @@ static const struct file_operations fuse_file_operations = {
802 .release = fuse_release, 802 .release = fuse_release,
803 .fsync = fuse_fsync, 803 .fsync = fuse_fsync,
804 .lock = fuse_file_lock, 804 .lock = fuse_file_lock,
805 .sendfile = generic_file_sendfile, 805 .splice_read = generic_file_splice_read,
806}; 806};
807 807
808static const struct file_operations fuse_direct_io_file_operations = { 808static const struct file_operations fuse_direct_io_file_operations = {
@@ -814,7 +814,7 @@ static const struct file_operations fuse_direct_io_file_operations = {
814 .release = fuse_release, 814 .release = fuse_release,
815 .fsync = fuse_fsync, 815 .fsync = fuse_fsync,
816 .lock = fuse_file_lock, 816 .lock = fuse_file_lock,
817 /* no mmap and sendfile */ 817 /* no mmap and splice_read */
818}; 818};
819 819
820static const struct address_space_operations fuse_file_aops = { 820static const struct address_space_operations fuse_file_aops = {
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 064df8804582..7dc3be108204 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -635,7 +635,6 @@ const struct file_operations gfs2_file_fops = {
635 .release = gfs2_close, 635 .release = gfs2_close,
636 .fsync = gfs2_fsync, 636 .fsync = gfs2_fsync,
637 .lock = gfs2_lock, 637 .lock = gfs2_lock,
638 .sendfile = generic_file_sendfile,
639 .flock = gfs2_flock, 638 .flock = gfs2_flock,
640 .splice_read = generic_file_splice_read, 639 .splice_read = generic_file_splice_read,
641 .splice_write = generic_file_splice_write, 640 .splice_write = generic_file_splice_write,
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 9a934db0bd8a..bc835f272a6e 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -607,7 +607,7 @@ static const struct file_operations hfs_file_operations = {
607 .write = do_sync_write, 607 .write = do_sync_write,
608 .aio_write = generic_file_aio_write, 608 .aio_write = generic_file_aio_write,
609 .mmap = generic_file_mmap, 609 .mmap = generic_file_mmap,
610 .sendfile = generic_file_sendfile, 610 .splice_read = generic_file_splice_read,
611 .fsync = file_fsync, 611 .fsync = file_fsync,
612 .open = hfs_file_open, 612 .open = hfs_file_open,
613 .release = hfs_file_release, 613 .release = hfs_file_release,
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 45dab5d6cc10..409ce5429c91 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -288,7 +288,7 @@ static const struct file_operations hfsplus_file_operations = {
288 .write = do_sync_write, 288 .write = do_sync_write,
289 .aio_write = generic_file_aio_write, 289 .aio_write = generic_file_aio_write,
290 .mmap = generic_file_mmap, 290 .mmap = generic_file_mmap,
291 .sendfile = generic_file_sendfile, 291 .splice_read = generic_file_splice_read,
292 .fsync = file_fsync, 292 .fsync = file_fsync,
293 .open = hfsplus_file_open, 293 .open = hfsplus_file_open,
294 .release = hfsplus_file_release, 294 .release = hfsplus_file_release,
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 8286491dbf31..c77862032e84 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -390,7 +390,7 @@ int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
390static const struct file_operations hostfs_file_fops = { 390static const struct file_operations hostfs_file_fops = {
391 .llseek = generic_file_llseek, 391 .llseek = generic_file_llseek,
392 .read = do_sync_read, 392 .read = do_sync_read,
393 .sendfile = generic_file_sendfile, 393 .splice_read = generic_file_splice_read,
394 .aio_read = generic_file_aio_read, 394 .aio_read = generic_file_aio_read,
395 .aio_write = generic_file_aio_write, 395 .aio_write = generic_file_aio_write,
396 .write = do_sync_write, 396 .write = do_sync_write,
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index b4eafc0f1e54..5b53e5c5d8df 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -129,7 +129,7 @@ const struct file_operations hpfs_file_ops =
129 .mmap = generic_file_mmap, 129 .mmap = generic_file_mmap,
130 .release = hpfs_file_release, 130 .release = hpfs_file_release,
131 .fsync = hpfs_file_fsync, 131 .fsync = hpfs_file_fsync,
132 .sendfile = generic_file_sendfile, 132 .splice_read = generic_file_splice_read,
133}; 133};
134 134
135const struct inode_operations hpfs_file_iops = 135const struct inode_operations hpfs_file_iops =
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 99871279a1ed..c2530197be0c 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -47,7 +47,7 @@ const struct file_operations jffs2_file_operations =
47 .ioctl = jffs2_ioctl, 47 .ioctl = jffs2_ioctl,
48 .mmap = generic_file_readonly_mmap, 48 .mmap = generic_file_readonly_mmap,
49 .fsync = jffs2_fsync, 49 .fsync = jffs2_fsync,
50 .sendfile = generic_file_sendfile 50 .splice_read = generic_file_splice_read,
51}; 51};
52 52
53/* jffs2_file_inode_operations */ 53/* jffs2_file_inode_operations */
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index f7f8eff19b7b..87eb93694af7 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -108,7 +108,6 @@ const struct file_operations jfs_file_operations = {
108 .aio_read = generic_file_aio_read, 108 .aio_read = generic_file_aio_read,
109 .aio_write = generic_file_aio_write, 109 .aio_write = generic_file_aio_write,
110 .mmap = generic_file_mmap, 110 .mmap = generic_file_mmap,
111 .sendfile = generic_file_sendfile,
112 .splice_read = generic_file_splice_read, 111 .splice_read = generic_file_splice_read,
113 .splice_write = generic_file_splice_write, 112 .splice_write = generic_file_splice_write,
114 .fsync = jfs_fsync, 113 .fsync = jfs_fsync,
diff --git a/fs/minix/file.c b/fs/minix/file.c
index f92baa1d7570..17765f697e50 100644
--- a/fs/minix/file.c
+++ b/fs/minix/file.c
@@ -23,7 +23,7 @@ const struct file_operations minix_file_operations = {
23 .aio_write = generic_file_aio_write, 23 .aio_write = generic_file_aio_write,
24 .mmap = generic_file_mmap, 24 .mmap = generic_file_mmap,
25 .fsync = minix_sync_file, 25 .fsync = minix_sync_file,
26 .sendfile = generic_file_sendfile, 26 .splice_read = generic_file_splice_read,
27}; 27};
28 28
29const struct inode_operations minix_file_inode_operations = { 29const struct inode_operations minix_file_inode_operations = {
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 9eb8eb4e4a08..8689b736fdd9 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -41,7 +41,9 @@ static int nfs_file_open(struct inode *, struct file *);
41static int nfs_file_release(struct inode *, struct file *); 41static int nfs_file_release(struct inode *, struct file *);
42static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin); 42static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin);
43static int nfs_file_mmap(struct file *, struct vm_area_struct *); 43static int nfs_file_mmap(struct file *, struct vm_area_struct *);
44static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); 44static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
45 struct pipe_inode_info *pipe,
46 size_t count, unsigned int flags);
45static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov, 47static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
46 unsigned long nr_segs, loff_t pos); 48 unsigned long nr_segs, loff_t pos);
47static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, 49static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
@@ -65,7 +67,7 @@ const struct file_operations nfs_file_operations = {
65 .fsync = nfs_fsync, 67 .fsync = nfs_fsync,
66 .lock = nfs_lock, 68 .lock = nfs_lock,
67 .flock = nfs_flock, 69 .flock = nfs_flock,
68 .sendfile = nfs_file_sendfile, 70 .splice_read = nfs_file_splice_read,
69 .check_flags = nfs_check_flags, 71 .check_flags = nfs_check_flags,
70}; 72};
71 73
@@ -224,20 +226,21 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
224} 226}
225 227
226static ssize_t 228static ssize_t
227nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count, 229nfs_file_splice_read(struct file *filp, loff_t *ppos,
228 read_actor_t actor, void *target) 230 struct pipe_inode_info *pipe, size_t count,
231 unsigned int flags)
229{ 232{
230 struct dentry *dentry = filp->f_path.dentry; 233 struct dentry *dentry = filp->f_path.dentry;
231 struct inode *inode = dentry->d_inode; 234 struct inode *inode = dentry->d_inode;
232 ssize_t res; 235 ssize_t res;
233 236
234 dfprintk(VFS, "nfs: sendfile(%s/%s, %lu@%Lu)\n", 237 dfprintk(VFS, "nfs: splice_read(%s/%s, %lu@%Lu)\n",
235 dentry->d_parent->d_name.name, dentry->d_name.name, 238 dentry->d_parent->d_name.name, dentry->d_name.name,
236 (unsigned long) count, (unsigned long long) *ppos); 239 (unsigned long) count, (unsigned long long) *ppos);
237 240
238 res = nfs_revalidate_mapping(inode, filp->f_mapping); 241 res = nfs_revalidate_mapping(inode, filp->f_mapping);
239 if (!res) 242 if (!res)
240 res = generic_file_sendfile(filp, ppos, count, actor, target); 243 res = generic_file_splice_read(filp, ppos, pipe, count, flags);
241 return res; 244 return res;
242} 245}
243 246
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 7e6aa245b5d5..8604e35bd48e 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -23,7 +23,7 @@
23#include <linux/file.h> 23#include <linux/file.h>
24#include <linux/mount.h> 24#include <linux/mount.h>
25#include <linux/major.h> 25#include <linux/major.h>
26#include <linux/ext2_fs.h> 26#include <linux/splice.h>
27#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
28#include <linux/stat.h> 28#include <linux/stat.h>
29#include <linux/fcntl.h> 29#include <linux/fcntl.h>
@@ -801,26 +801,32 @@ found:
801} 801}
802 802
803/* 803/*
804 * Grab and keep cached pages assosiated with a file in the svc_rqst 804 * Grab and keep cached pages associated with a file in the svc_rqst
805 * so that they can be passed to the netowork sendmsg/sendpage routines 805 * so that they can be passed to the network sendmsg/sendpage routines
806 * directrly. They will be released after the sending has completed. 806 * directly. They will be released after the sending has completed.
807 */ 807 */
808static int 808static int
809nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset , unsigned long size) 809nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
810 struct splice_desc *sd)
810{ 811{
811 unsigned long count = desc->count; 812 struct svc_rqst *rqstp = sd->u.data;
812 struct svc_rqst *rqstp = desc->arg.data;
813 struct page **pp = rqstp->rq_respages + rqstp->rq_resused; 813 struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
814 struct page *page = buf->page;
815 size_t size;
816 int ret;
817
818 ret = buf->ops->confirm(pipe, buf);
819 if (unlikely(ret))
820 return ret;
814 821
815 if (size > count) 822 size = sd->len;
816 size = count;
817 823
818 if (rqstp->rq_res.page_len == 0) { 824 if (rqstp->rq_res.page_len == 0) {
819 get_page(page); 825 get_page(page);
820 put_page(*pp); 826 put_page(*pp);
821 *pp = page; 827 *pp = page;
822 rqstp->rq_resused++; 828 rqstp->rq_resused++;
823 rqstp->rq_res.page_base = offset; 829 rqstp->rq_res.page_base = buf->offset;
824 rqstp->rq_res.page_len = size; 830 rqstp->rq_res.page_len = size;
825 } else if (page != pp[-1]) { 831 } else if (page != pp[-1]) {
826 get_page(page); 832 get_page(page);
@@ -832,11 +838,15 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset
832 } else 838 } else
833 rqstp->rq_res.page_len += size; 839 rqstp->rq_res.page_len += size;
834 840
835 desc->count = count - size;
836 desc->written += size;
837 return size; 841 return size;
838} 842}
839 843
844static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
845 struct splice_desc *sd)
846{
847 return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
848}
849
840static __be32 850static __be32
841nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, 851nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
842 loff_t offset, struct kvec *vec, int vlen, unsigned long *count) 852 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
@@ -861,10 +871,15 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
861 if (ra && ra->p_set) 871 if (ra && ra->p_set)
862 file->f_ra = ra->p_ra; 872 file->f_ra = ra->p_ra;
863 873
864 if (file->f_op->sendfile && rqstp->rq_sendfile_ok) { 874 if (file->f_op->splice_read && rqstp->rq_splice_ok) {
865 rqstp->rq_resused = 1; 875 struct splice_desc sd = {
866 host_err = file->f_op->sendfile(file, &offset, *count, 876 .len = 0,
867 nfsd_read_actor, rqstp); 877 .total_len = *count,
878 .pos = offset,
879 .u.data = rqstp,
880 };
881
882 host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
868 } else { 883 } else {
869 oldfs = get_fs(); 884 oldfs = get_fs();
870 set_fs(KERNEL_DS); 885 set_fs(KERNEL_DS);
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 7ed56390b582..ffcc504a1667 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -2276,7 +2276,7 @@ const struct file_operations ntfs_file_ops = {
2276 mounted filesystem. */ 2276 mounted filesystem. */
2277 .mmap = generic_file_mmap, /* Mmap file. */ 2277 .mmap = generic_file_mmap, /* Mmap file. */
2278 .open = ntfs_file_open, /* Open file. */ 2278 .open = ntfs_file_open, /* Open file. */
2279 .sendfile = generic_file_sendfile, /* Zero-copy data send with 2279 .splice_read = generic_file_splice_read /* Zero-copy data send with
2280 the data source being on 2280 the data source being on
2281 the ntfs partition. We do 2281 the ntfs partition. We do
2282 not need to care about the 2282 not need to care about the
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index ac6c96431bbc..4979b6675717 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -31,7 +31,7 @@
31#include <linux/pagemap.h> 31#include <linux/pagemap.h>
32#include <linux/uio.h> 32#include <linux/uio.h>
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <linux/pipe_fs_i.h> 34#include <linux/splice.h>
35#include <linux/mount.h> 35#include <linux/mount.h>
36#include <linux/writeback.h> 36#include <linux/writeback.h>
37 37
@@ -1583,7 +1583,7 @@ static int ocfs2_splice_write_actor(struct pipe_inode_info *pipe,
1583 ssize_t copied = 0; 1583 ssize_t copied = 0;
1584 struct ocfs2_splice_write_priv sp; 1584 struct ocfs2_splice_write_priv sp;
1585 1585
1586 ret = buf->ops->pin(pipe, buf); 1586 ret = buf->ops->confirm(pipe, buf);
1587 if (ret) 1587 if (ret)
1588 goto out; 1588 goto out;
1589 1589
@@ -1604,7 +1604,7 @@ static int ocfs2_splice_write_actor(struct pipe_inode_info *pipe,
1604 * might enter ocfs2_buffered_write_cluster() more 1604 * might enter ocfs2_buffered_write_cluster() more
1605 * than once, so keep track of our progress here. 1605 * than once, so keep track of our progress here.
1606 */ 1606 */
1607 copied = ocfs2_buffered_write_cluster(sd->file, 1607 copied = ocfs2_buffered_write_cluster(sd->u.file,
1608 (loff_t)sd->pos + total, 1608 (loff_t)sd->pos + total,
1609 count, 1609 count,
1610 ocfs2_map_and_write_splice_data, 1610 ocfs2_map_and_write_splice_data,
@@ -1636,9 +1636,14 @@ static ssize_t __ocfs2_file_splice_write(struct pipe_inode_info *pipe,
1636 int ret, err; 1636 int ret, err;
1637 struct address_space *mapping = out->f_mapping; 1637 struct address_space *mapping = out->f_mapping;
1638 struct inode *inode = mapping->host; 1638 struct inode *inode = mapping->host;
1639 1639 struct splice_desc sd = {
1640 ret = __splice_from_pipe(pipe, out, ppos, len, flags, 1640 .total_len = len,
1641 ocfs2_splice_write_actor); 1641 .flags = flags,
1642 .pos = *ppos,
1643 .u.file = out,
1644 };
1645
1646 ret = __splice_from_pipe(pipe, &sd, ocfs2_splice_write_actor);
1642 if (ret > 0) { 1647 if (ret > 0) {
1643 *ppos += ret; 1648 *ppos += ret;
1644 1649
@@ -1817,7 +1822,6 @@ const struct inode_operations ocfs2_special_file_iops = {
1817const struct file_operations ocfs2_fops = { 1822const struct file_operations ocfs2_fops = {
1818 .read = do_sync_read, 1823 .read = do_sync_read,
1819 .write = do_sync_write, 1824 .write = do_sync_write,
1820 .sendfile = generic_file_sendfile,
1821 .mmap = ocfs2_mmap, 1825 .mmap = ocfs2_mmap,
1822 .fsync = ocfs2_sync_file, 1826 .fsync = ocfs2_sync_file,
1823 .release = ocfs2_file_release, 1827 .release = ocfs2_file_release,
diff --git a/fs/pipe.c b/fs/pipe.c
index 3a89592bdf57..d007830d9c87 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -164,6 +164,20 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
164 page_cache_release(page); 164 page_cache_release(page);
165} 165}
166 166
167/**
168 * generic_pipe_buf_map - virtually map a pipe buffer
169 * @pipe: the pipe that the buffer belongs to
170 * @buf: the buffer that should be mapped
171 * @atomic: whether to use an atomic map
172 *
173 * Description:
174 * This function returns a kernel virtual address mapping for the
175 * passed in @pipe_buffer. If @atomic is set, an atomic map is provided
176 * and the caller has to be careful not to fault before calling
177 * the unmap function.
178 *
179 * Note that this function occupies KM_USER0 if @atomic != 0.
180 */
167void *generic_pipe_buf_map(struct pipe_inode_info *pipe, 181void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
168 struct pipe_buffer *buf, int atomic) 182 struct pipe_buffer *buf, int atomic)
169{ 183{
@@ -175,6 +189,15 @@ void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
175 return kmap(buf->page); 189 return kmap(buf->page);
176} 190}
177 191
192/**
193 * generic_pipe_buf_unmap - unmap a previously mapped pipe buffer
194 * @pipe: the pipe that the buffer belongs to
195 * @buf: the buffer that should be unmapped
196 * @map_data: the data that the mapping function returned
197 *
198 * Description:
199 * This function undoes the mapping that ->map() provided.
200 */
178void generic_pipe_buf_unmap(struct pipe_inode_info *pipe, 201void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
179 struct pipe_buffer *buf, void *map_data) 202 struct pipe_buffer *buf, void *map_data)
180{ 203{
@@ -185,11 +208,28 @@ void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
185 kunmap(buf->page); 208 kunmap(buf->page);
186} 209}
187 210
211/**
212 * generic_pipe_buf_steal - attempt to take ownership of a @pipe_buffer
213 * @pipe: the pipe that the buffer belongs to
214 * @buf: the buffer to attempt to steal
215 *
216 * Description:
217 * This function attempts to steal the @struct page attached to
218 * @buf. If successful, this function returns 0 and returns with
219 * the page locked. The caller may then reuse the page for whatever
220 * he wishes, the typical use is insertion into a different file
221 * page cache.
222 */
188int generic_pipe_buf_steal(struct pipe_inode_info *pipe, 223int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
189 struct pipe_buffer *buf) 224 struct pipe_buffer *buf)
190{ 225{
191 struct page *page = buf->page; 226 struct page *page = buf->page;
192 227
228 /*
229 * A reference of one is golden, that means that the owner of this
230 * page is the only one holding a reference to it. lock the page
231 * and return OK.
232 */
193 if (page_count(page) == 1) { 233 if (page_count(page) == 1) {
194 lock_page(page); 234 lock_page(page);
195 return 0; 235 return 0;
@@ -198,12 +238,32 @@ int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
198 return 1; 238 return 1;
199} 239}
200 240
201void generic_pipe_buf_get(struct pipe_inode_info *info, struct pipe_buffer *buf) 241/**
242 * generic_pipe_buf_get - get a reference to a @struct pipe_buffer
243 * @pipe: the pipe that the buffer belongs to
244 * @buf: the buffer to get a reference to
245 *
246 * Description:
247 * This function grabs an extra reference to @buf. It's used in
248 * in the tee() system call, when we duplicate the buffers in one
249 * pipe into another.
250 */
251void generic_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
202{ 252{
203 page_cache_get(buf->page); 253 page_cache_get(buf->page);
204} 254}
205 255
206int generic_pipe_buf_pin(struct pipe_inode_info *info, struct pipe_buffer *buf) 256/**
257 * generic_pipe_buf_confirm - verify contents of the pipe buffer
258 * @pipe: the pipe that the buffer belongs to
259 * @buf: the buffer to confirm
260 *
261 * Description:
262 * This function does nothing, because the generic pipe code uses
263 * pages that are always good when inserted into the pipe.
264 */
265int generic_pipe_buf_confirm(struct pipe_inode_info *info,
266 struct pipe_buffer *buf)
207{ 267{
208 return 0; 268 return 0;
209} 269}
@@ -212,7 +272,7 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = {
212 .can_merge = 1, 272 .can_merge = 1,
213 .map = generic_pipe_buf_map, 273 .map = generic_pipe_buf_map,
214 .unmap = generic_pipe_buf_unmap, 274 .unmap = generic_pipe_buf_unmap,
215 .pin = generic_pipe_buf_pin, 275 .confirm = generic_pipe_buf_confirm,
216 .release = anon_pipe_buf_release, 276 .release = anon_pipe_buf_release,
217 .steal = generic_pipe_buf_steal, 277 .steal = generic_pipe_buf_steal,
218 .get = generic_pipe_buf_get, 278 .get = generic_pipe_buf_get,
@@ -252,7 +312,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov,
252 if (chars > total_len) 312 if (chars > total_len)
253 chars = total_len; 313 chars = total_len;
254 314
255 error = ops->pin(pipe, buf); 315 error = ops->confirm(pipe, buf);
256 if (error) { 316 if (error) {
257 if (!ret) 317 if (!ret)
258 error = ret; 318 error = ret;
@@ -373,7 +433,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov,
373 int error, atomic = 1; 433 int error, atomic = 1;
374 void *addr; 434 void *addr;
375 435
376 error = ops->pin(pipe, buf); 436 error = ops->confirm(pipe, buf);
377 if (error) 437 if (error)
378 goto out; 438 goto out;
379 439
diff --git a/fs/qnx4/file.c b/fs/qnx4/file.c
index 44649981bbc8..867f42b02035 100644
--- a/fs/qnx4/file.c
+++ b/fs/qnx4/file.c
@@ -25,7 +25,7 @@ const struct file_operations qnx4_file_operations =
25 .read = do_sync_read, 25 .read = do_sync_read,
26 .aio_read = generic_file_aio_read, 26 .aio_read = generic_file_aio_read,
27 .mmap = generic_file_mmap, 27 .mmap = generic_file_mmap,
28 .sendfile = generic_file_sendfile, 28 .splice_read = generic_file_splice_read,
29#ifdef CONFIG_QNX4FS_RW 29#ifdef CONFIG_QNX4FS_RW
30 .write = do_sync_write, 30 .write = do_sync_write,
31 .aio_write = generic_file_aio_write, 31 .aio_write = generic_file_aio_write,
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c
index 2f14774a124f..97bdc0b2f9d2 100644
--- a/fs/ramfs/file-mmu.c
+++ b/fs/ramfs/file-mmu.c
@@ -41,7 +41,7 @@ const struct file_operations ramfs_file_operations = {
41 .aio_write = generic_file_aio_write, 41 .aio_write = generic_file_aio_write,
42 .mmap = generic_file_mmap, 42 .mmap = generic_file_mmap,
43 .fsync = simple_sync_file, 43 .fsync = simple_sync_file,
44 .sendfile = generic_file_sendfile, 44 .splice_read = generic_file_splice_read,
45 .llseek = generic_file_llseek, 45 .llseek = generic_file_llseek,
46}; 46};
47 47
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 5d258c40a2fd..cad2b7ace630 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -42,7 +42,7 @@ const struct file_operations ramfs_file_operations = {
42 .write = do_sync_write, 42 .write = do_sync_write,
43 .aio_write = generic_file_aio_write, 43 .aio_write = generic_file_aio_write,
44 .fsync = simple_sync_file, 44 .fsync = simple_sync_file,
45 .sendfile = generic_file_sendfile, 45 .splice_read = generic_file_splice_read,
46 .llseek = generic_file_llseek, 46 .llseek = generic_file_llseek,
47}; 47};
48 48
diff --git a/fs/read_write.c b/fs/read_write.c
index 4d03008f015b..507ddff48a9a 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/syscalls.h> 16#include <linux/syscalls.h>
17#include <linux/pagemap.h> 17#include <linux/pagemap.h>
18#include <linux/splice.h>
18#include "read_write.h" 19#include "read_write.h"
19 20
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
@@ -25,7 +26,7 @@ const struct file_operations generic_ro_fops = {
25 .read = do_sync_read, 26 .read = do_sync_read,
26 .aio_read = generic_file_aio_read, 27 .aio_read = generic_file_aio_read,
27 .mmap = generic_file_readonly_mmap, 28 .mmap = generic_file_readonly_mmap,
28 .sendfile = generic_file_sendfile, 29 .splice_read = generic_file_splice_read,
29}; 30};
30 31
31EXPORT_SYMBOL(generic_ro_fops); 32EXPORT_SYMBOL(generic_ro_fops);
@@ -708,7 +709,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
708 struct inode * in_inode, * out_inode; 709 struct inode * in_inode, * out_inode;
709 loff_t pos; 710 loff_t pos;
710 ssize_t retval; 711 ssize_t retval;
711 int fput_needed_in, fput_needed_out; 712 int fput_needed_in, fput_needed_out, fl;
712 713
713 /* 714 /*
714 * Get input file, and verify that it is ok.. 715 * Get input file, and verify that it is ok..
@@ -723,7 +724,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
723 in_inode = in_file->f_path.dentry->d_inode; 724 in_inode = in_file->f_path.dentry->d_inode;
724 if (!in_inode) 725 if (!in_inode)
725 goto fput_in; 726 goto fput_in;
726 if (!in_file->f_op || !in_file->f_op->sendfile) 727 if (!in_file->f_op || !in_file->f_op->splice_read)
727 goto fput_in; 728 goto fput_in;
728 retval = -ESPIPE; 729 retval = -ESPIPE;
729 if (!ppos) 730 if (!ppos)
@@ -776,7 +777,18 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
776 count = max - pos; 777 count = max - pos;
777 } 778 }
778 779
779 retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file); 780 fl = 0;
781#if 0
782 /*
783 * We need to debate whether we can enable this or not. The
784 * man page documents EAGAIN return for the output at least,
785 * and the application is arguably buggy if it doesn't expect
786 * EAGAIN on a non-blocking file descriptor.
787 */
788 if (in_file->f_flags & O_NONBLOCK)
789 fl = SPLICE_F_NONBLOCK;
790#endif
791 retval = do_splice_direct(in_file, ppos, out_file, count, fl);
780 792
781 if (retval > 0) { 793 if (retval > 0) {
782 add_rchar(current, retval); 794 add_rchar(current, retval);
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 9e451a68580f..30eebfb1b2d8 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -1531,7 +1531,6 @@ const struct file_operations reiserfs_file_operations = {
1531 .open = generic_file_open, 1531 .open = generic_file_open,
1532 .release = reiserfs_file_release, 1532 .release = reiserfs_file_release,
1533 .fsync = reiserfs_sync_file, 1533 .fsync = reiserfs_sync_file,
1534 .sendfile = generic_file_sendfile,
1535 .aio_read = generic_file_aio_read, 1534 .aio_read = generic_file_aio_read,
1536 .aio_write = generic_file_aio_write, 1535 .aio_write = generic_file_aio_write,
1537 .splice_read = generic_file_splice_read, 1536 .splice_read = generic_file_splice_read,
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index aea3f8aa54c0..c5d78a7e492b 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -262,8 +262,9 @@ out:
262} 262}
263 263
264static ssize_t 264static ssize_t
265smb_file_sendfile(struct file *file, loff_t *ppos, 265smb_file_splice_read(struct file *file, loff_t *ppos,
266 size_t count, read_actor_t actor, void *target) 266 struct pipe_inode_info *pipe, size_t count,
267 unsigned int flags)
267{ 268{
268 struct dentry *dentry = file->f_path.dentry; 269 struct dentry *dentry = file->f_path.dentry;
269 ssize_t status; 270 ssize_t status;
@@ -277,7 +278,7 @@ smb_file_sendfile(struct file *file, loff_t *ppos,
277 DENTRY_PATH(dentry), status); 278 DENTRY_PATH(dentry), status);
278 goto out; 279 goto out;
279 } 280 }
280 status = generic_file_sendfile(file, ppos, count, actor, target); 281 status = generic_file_splice_read(file, ppos, pipe, count, flags);
281out: 282out:
282 return status; 283 return status;
283} 284}
@@ -416,7 +417,7 @@ const struct file_operations smb_file_operations =
416 .open = smb_file_open, 417 .open = smb_file_open,
417 .release = smb_file_release, 418 .release = smb_file_release,
418 .fsync = smb_fsync, 419 .fsync = smb_fsync,
419 .sendfile = smb_file_sendfile, 420 .splice_read = smb_file_splice_read,
420}; 421};
421 422
422const struct inode_operations smb_file_inode_operations = 423const struct inode_operations smb_file_inode_operations =
diff --git a/fs/splice.c b/fs/splice.c
index e7d7080de2f9..ed2ce995475c 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -20,7 +20,7 @@
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/file.h> 21#include <linux/file.h>
22#include <linux/pagemap.h> 22#include <linux/pagemap.h>
23#include <linux/pipe_fs_i.h> 23#include <linux/splice.h>
24#include <linux/mm_inline.h> 24#include <linux/mm_inline.h>
25#include <linux/swap.h> 25#include <linux/swap.h>
26#include <linux/writeback.h> 26#include <linux/writeback.h>
@@ -29,22 +29,6 @@
29#include <linux/syscalls.h> 29#include <linux/syscalls.h>
30#include <linux/uio.h> 30#include <linux/uio.h>
31 31
32struct partial_page {
33 unsigned int offset;
34 unsigned int len;
35};
36
37/*
38 * Passed to splice_to_pipe
39 */
40struct splice_pipe_desc {
41 struct page **pages; /* page map */
42 struct partial_page *partial; /* pages[] may not be contig */
43 int nr_pages; /* number of pages in map */
44 unsigned int flags; /* splice flags */
45 const struct pipe_buf_operations *ops;/* ops associated with output pipe */
46};
47
48/* 32/*
49 * Attempt to steal a page from a pipe buffer. This should perhaps go into 33 * Attempt to steal a page from a pipe buffer. This should perhaps go into
50 * a vm helper function, it's already simplified quite a bit by the 34 * a vm helper function, it's already simplified quite a bit by the
@@ -101,8 +85,12 @@ static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe,
101 buf->flags &= ~PIPE_BUF_FLAG_LRU; 85 buf->flags &= ~PIPE_BUF_FLAG_LRU;
102} 86}
103 87
104static int page_cache_pipe_buf_pin(struct pipe_inode_info *pipe, 88/*
105 struct pipe_buffer *buf) 89 * Check whether the contents of buf is OK to access. Since the content
90 * is a page cache page, IO may be in flight.
91 */
92static int page_cache_pipe_buf_confirm(struct pipe_inode_info *pipe,
93 struct pipe_buffer *buf)
106{ 94{
107 struct page *page = buf->page; 95 struct page *page = buf->page;
108 int err; 96 int err;
@@ -143,7 +131,7 @@ static const struct pipe_buf_operations page_cache_pipe_buf_ops = {
143 .can_merge = 0, 131 .can_merge = 0,
144 .map = generic_pipe_buf_map, 132 .map = generic_pipe_buf_map,
145 .unmap = generic_pipe_buf_unmap, 133 .unmap = generic_pipe_buf_unmap,
146 .pin = page_cache_pipe_buf_pin, 134 .confirm = page_cache_pipe_buf_confirm,
147 .release = page_cache_pipe_buf_release, 135 .release = page_cache_pipe_buf_release,
148 .steal = page_cache_pipe_buf_steal, 136 .steal = page_cache_pipe_buf_steal,
149 .get = generic_pipe_buf_get, 137 .get = generic_pipe_buf_get,
@@ -163,18 +151,25 @@ static const struct pipe_buf_operations user_page_pipe_buf_ops = {
163 .can_merge = 0, 151 .can_merge = 0,
164 .map = generic_pipe_buf_map, 152 .map = generic_pipe_buf_map,
165 .unmap = generic_pipe_buf_unmap, 153 .unmap = generic_pipe_buf_unmap,
166 .pin = generic_pipe_buf_pin, 154 .confirm = generic_pipe_buf_confirm,
167 .release = page_cache_pipe_buf_release, 155 .release = page_cache_pipe_buf_release,
168 .steal = user_page_pipe_buf_steal, 156 .steal = user_page_pipe_buf_steal,
169 .get = generic_pipe_buf_get, 157 .get = generic_pipe_buf_get,
170}; 158};
171 159
172/* 160/**
173 * Pipe output worker. This sets up our pipe format with the page cache 161 * splice_to_pipe - fill passed data into a pipe
174 * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). 162 * @pipe: pipe to fill
163 * @spd: data to fill
164 *
165 * Description:
166 * @spd contains a map of pages and len/offset tupples, a long with
167 * the struct pipe_buf_operations associated with these pages. This
168 * function will link that data to the pipe.
169 *
175 */ 170 */
176static ssize_t splice_to_pipe(struct pipe_inode_info *pipe, 171ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
177 struct splice_pipe_desc *spd) 172 struct splice_pipe_desc *spd)
178{ 173{
179 unsigned int spd_pages = spd->nr_pages; 174 unsigned int spd_pages = spd->nr_pages;
180 int ret, do_wakeup, page_nr; 175 int ret, do_wakeup, page_nr;
@@ -201,6 +196,7 @@ static ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
201 buf->page = spd->pages[page_nr]; 196 buf->page = spd->pages[page_nr];
202 buf->offset = spd->partial[page_nr].offset; 197 buf->offset = spd->partial[page_nr].offset;
203 buf->len = spd->partial[page_nr].len; 198 buf->len = spd->partial[page_nr].len;
199 buf->private = spd->partial[page_nr].private;
204 buf->ops = spd->ops; 200 buf->ops = spd->ops;
205 if (spd->flags & SPLICE_F_GIFT) 201 if (spd->flags & SPLICE_F_GIFT)
206 buf->flags |= PIPE_BUF_FLAG_GIFT; 202 buf->flags |= PIPE_BUF_FLAG_GIFT;
@@ -296,19 +292,15 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
296 page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages); 292 page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages);
297 293
298 /* 294 /*
299 * Now fill in the holes:
300 */
301 error = 0;
302
303 /*
304 * Lookup the (hopefully) full range of pages we need. 295 * Lookup the (hopefully) full range of pages we need.
305 */ 296 */
306 spd.nr_pages = find_get_pages_contig(mapping, index, nr_pages, pages); 297 spd.nr_pages = find_get_pages_contig(mapping, index, nr_pages, pages);
307 298
308 /* 299 /*
309 * If find_get_pages_contig() returned fewer pages than we needed, 300 * If find_get_pages_contig() returned fewer pages than we needed,
310 * allocate the rest. 301 * allocate the rest and fill in the holes.
311 */ 302 */
303 error = 0;
312 index += spd.nr_pages; 304 index += spd.nr_pages;
313 while (spd.nr_pages < nr_pages) { 305 while (spd.nr_pages < nr_pages) {
314 /* 306 /*
@@ -470,11 +462,16 @@ fill_it:
470/** 462/**
471 * generic_file_splice_read - splice data from file to a pipe 463 * generic_file_splice_read - splice data from file to a pipe
472 * @in: file to splice from 464 * @in: file to splice from
465 * @ppos: position in @in
473 * @pipe: pipe to splice to 466 * @pipe: pipe to splice to
474 * @len: number of bytes to splice 467 * @len: number of bytes to splice
475 * @flags: splice modifier flags 468 * @flags: splice modifier flags
476 * 469 *
477 * Will read pages from given file and fill them into a pipe. 470 * Description:
471 * Will read pages from given file and fill them into a pipe. Can be
472 * used as long as the address_space operations for the source implements
473 * a readpage() hook.
474 *
478 */ 475 */
479ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, 476ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
480 struct pipe_inode_info *pipe, size_t len, 477 struct pipe_inode_info *pipe, size_t len,
@@ -528,11 +525,11 @@ EXPORT_SYMBOL(generic_file_splice_read);
528static int pipe_to_sendpage(struct pipe_inode_info *pipe, 525static int pipe_to_sendpage(struct pipe_inode_info *pipe,
529 struct pipe_buffer *buf, struct splice_desc *sd) 526 struct pipe_buffer *buf, struct splice_desc *sd)
530{ 527{
531 struct file *file = sd->file; 528 struct file *file = sd->u.file;
532 loff_t pos = sd->pos; 529 loff_t pos = sd->pos;
533 int ret, more; 530 int ret, more;
534 531
535 ret = buf->ops->pin(pipe, buf); 532 ret = buf->ops->confirm(pipe, buf);
536 if (!ret) { 533 if (!ret) {
537 more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; 534 more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
538 535
@@ -566,7 +563,7 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
566static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, 563static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
567 struct splice_desc *sd) 564 struct splice_desc *sd)
568{ 565{
569 struct file *file = sd->file; 566 struct file *file = sd->u.file;
570 struct address_space *mapping = file->f_mapping; 567 struct address_space *mapping = file->f_mapping;
571 unsigned int offset, this_len; 568 unsigned int offset, this_len;
572 struct page *page; 569 struct page *page;
@@ -576,7 +573,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
576 /* 573 /*
577 * make sure the data in this buffer is uptodate 574 * make sure the data in this buffer is uptodate
578 */ 575 */
579 ret = buf->ops->pin(pipe, buf); 576 ret = buf->ops->confirm(pipe, buf);
580 if (unlikely(ret)) 577 if (unlikely(ret))
581 return ret; 578 return ret;
582 579
@@ -663,36 +660,37 @@ out_ret:
663 return ret; 660 return ret;
664} 661}
665 662
666/* 663/**
667 * Pipe input worker. Most of this logic works like a regular pipe, the 664 * __splice_from_pipe - splice data from a pipe to given actor
668 * key here is the 'actor' worker passed in that actually moves the data 665 * @pipe: pipe to splice from
669 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. 666 * @sd: information to @actor
667 * @actor: handler that splices the data
668 *
669 * Description:
670 * This function does little more than loop over the pipe and call
671 * @actor to do the actual moving of a single struct pipe_buffer to
672 * the desired destination. See pipe_to_file, pipe_to_sendpage, or
673 * pipe_to_user.
674 *
670 */ 675 */
671ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, 676ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
672 struct file *out, loff_t *ppos, size_t len, 677 splice_actor *actor)
673 unsigned int flags, splice_actor *actor)
674{ 678{
675 int ret, do_wakeup, err; 679 int ret, do_wakeup, err;
676 struct splice_desc sd;
677 680
678 ret = 0; 681 ret = 0;
679 do_wakeup = 0; 682 do_wakeup = 0;
680 683
681 sd.total_len = len;
682 sd.flags = flags;
683 sd.file = out;
684 sd.pos = *ppos;
685
686 for (;;) { 684 for (;;) {
687 if (pipe->nrbufs) { 685 if (pipe->nrbufs) {
688 struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; 686 struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
689 const struct pipe_buf_operations *ops = buf->ops; 687 const struct pipe_buf_operations *ops = buf->ops;
690 688
691 sd.len = buf->len; 689 sd->len = buf->len;
692 if (sd.len > sd.total_len) 690 if (sd->len > sd->total_len)
693 sd.len = sd.total_len; 691 sd->len = sd->total_len;
694 692
695 err = actor(pipe, buf, &sd); 693 err = actor(pipe, buf, sd);
696 if (err <= 0) { 694 if (err <= 0) {
697 if (!ret && err != -ENODATA) 695 if (!ret && err != -ENODATA)
698 ret = err; 696 ret = err;
@@ -704,10 +702,10 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
704 buf->offset += err; 702 buf->offset += err;
705 buf->len -= err; 703 buf->len -= err;
706 704
707 sd.len -= err; 705 sd->len -= err;
708 sd.pos += err; 706 sd->pos += err;
709 sd.total_len -= err; 707 sd->total_len -= err;
710 if (sd.len) 708 if (sd->len)
711 continue; 709 continue;
712 710
713 if (!buf->len) { 711 if (!buf->len) {
@@ -719,7 +717,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
719 do_wakeup = 1; 717 do_wakeup = 1;
720 } 718 }
721 719
722 if (!sd.total_len) 720 if (!sd->total_len)
723 break; 721 break;
724 } 722 }
725 723
@@ -732,7 +730,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
732 break; 730 break;
733 } 731 }
734 732
735 if (flags & SPLICE_F_NONBLOCK) { 733 if (sd->flags & SPLICE_F_NONBLOCK) {
736 if (!ret) 734 if (!ret)
737 ret = -EAGAIN; 735 ret = -EAGAIN;
738 break; 736 break;
@@ -766,12 +764,32 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
766} 764}
767EXPORT_SYMBOL(__splice_from_pipe); 765EXPORT_SYMBOL(__splice_from_pipe);
768 766
767/**
768 * splice_from_pipe - splice data from a pipe to a file
769 * @pipe: pipe to splice from
770 * @out: file to splice to
771 * @ppos: position in @out
772 * @len: how many bytes to splice
773 * @flags: splice modifier flags
774 * @actor: handler that splices the data
775 *
776 * Description:
777 * See __splice_from_pipe. This function locks the input and output inodes,
778 * otherwise it's identical to __splice_from_pipe().
779 *
780 */
769ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, 781ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
770 loff_t *ppos, size_t len, unsigned int flags, 782 loff_t *ppos, size_t len, unsigned int flags,
771 splice_actor *actor) 783 splice_actor *actor)
772{ 784{
773 ssize_t ret; 785 ssize_t ret;
774 struct inode *inode = out->f_mapping->host; 786 struct inode *inode = out->f_mapping->host;
787 struct splice_desc sd = {
788 .total_len = len,
789 .flags = flags,
790 .pos = *ppos,
791 .u.file = out,
792 };
775 793
776 /* 794 /*
777 * The actor worker might be calling ->prepare_write and 795 * The actor worker might be calling ->prepare_write and
@@ -780,7 +798,7 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
780 * pipe->inode, we have to order lock acquiry here. 798 * pipe->inode, we have to order lock acquiry here.
781 */ 799 */
782 inode_double_lock(inode, pipe->inode); 800 inode_double_lock(inode, pipe->inode);
783 ret = __splice_from_pipe(pipe, out, ppos, len, flags, actor); 801 ret = __splice_from_pipe(pipe, &sd, actor);
784 inode_double_unlock(inode, pipe->inode); 802 inode_double_unlock(inode, pipe->inode);
785 803
786 return ret; 804 return ret;
@@ -790,12 +808,14 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
790 * generic_file_splice_write_nolock - generic_file_splice_write without mutexes 808 * generic_file_splice_write_nolock - generic_file_splice_write without mutexes
791 * @pipe: pipe info 809 * @pipe: pipe info
792 * @out: file to write to 810 * @out: file to write to
811 * @ppos: position in @out
793 * @len: number of bytes to splice 812 * @len: number of bytes to splice
794 * @flags: splice modifier flags 813 * @flags: splice modifier flags
795 * 814 *
796 * Will either move or copy pages (determined by @flags options) from 815 * Description:
797 * the given pipe inode to the given file. The caller is responsible 816 * Will either move or copy pages (determined by @flags options) from
798 * for acquiring i_mutex on both inodes. 817 * the given pipe inode to the given file. The caller is responsible
818 * for acquiring i_mutex on both inodes.
799 * 819 *
800 */ 820 */
801ssize_t 821ssize_t
@@ -804,6 +824,12 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
804{ 824{
805 struct address_space *mapping = out->f_mapping; 825 struct address_space *mapping = out->f_mapping;
806 struct inode *inode = mapping->host; 826 struct inode *inode = mapping->host;
827 struct splice_desc sd = {
828 .total_len = len,
829 .flags = flags,
830 .pos = *ppos,
831 .u.file = out,
832 };
807 ssize_t ret; 833 ssize_t ret;
808 int err; 834 int err;
809 835
@@ -811,7 +837,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
811 if (unlikely(err)) 837 if (unlikely(err))
812 return err; 838 return err;
813 839
814 ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); 840 ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
815 if (ret > 0) { 841 if (ret > 0) {
816 unsigned long nr_pages; 842 unsigned long nr_pages;
817 843
@@ -841,11 +867,13 @@ EXPORT_SYMBOL(generic_file_splice_write_nolock);
841 * generic_file_splice_write - splice data from a pipe to a file 867 * generic_file_splice_write - splice data from a pipe to a file
842 * @pipe: pipe info 868 * @pipe: pipe info
843 * @out: file to write to 869 * @out: file to write to
870 * @ppos: position in @out
844 * @len: number of bytes to splice 871 * @len: number of bytes to splice
845 * @flags: splice modifier flags 872 * @flags: splice modifier flags
846 * 873 *
847 * Will either move or copy pages (determined by @flags options) from 874 * Description:
848 * the given pipe inode to the given file. 875 * Will either move or copy pages (determined by @flags options) from
876 * the given pipe inode to the given file.
849 * 877 *
850 */ 878 */
851ssize_t 879ssize_t
@@ -896,13 +924,15 @@ EXPORT_SYMBOL(generic_file_splice_write);
896 924
897/** 925/**
898 * generic_splice_sendpage - splice data from a pipe to a socket 926 * generic_splice_sendpage - splice data from a pipe to a socket
899 * @inode: pipe inode 927 * @pipe: pipe to splice from
900 * @out: socket to write to 928 * @out: socket to write to
929 * @ppos: position in @out
901 * @len: number of bytes to splice 930 * @len: number of bytes to splice
902 * @flags: splice modifier flags 931 * @flags: splice modifier flags
903 * 932 *
904 * Will send @len bytes from the pipe to a network socket. No data copying 933 * Description:
905 * is involved. 934 * Will send @len bytes from the pipe to a network socket. No data copying
935 * is involved.
906 * 936 *
907 */ 937 */
908ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, 938ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out,
@@ -956,14 +986,27 @@ static long do_splice_to(struct file *in, loff_t *ppos,
956 return in->f_op->splice_read(in, ppos, pipe, len, flags); 986 return in->f_op->splice_read(in, ppos, pipe, len, flags);
957} 987}
958 988
959long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, 989/**
960 size_t len, unsigned int flags) 990 * splice_direct_to_actor - splices data directly between two non-pipes
991 * @in: file to splice from
992 * @sd: actor information on where to splice to
993 * @actor: handles the data splicing
994 *
995 * Description:
996 * This is a special case helper to splice directly between two
997 * points, without requiring an explicit pipe. Internally an allocated
998 * pipe is cached in the process, and reused during the life time of
999 * that process.
1000 *
1001 */
1002ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
1003 splice_direct_actor *actor)
961{ 1004{
962 struct pipe_inode_info *pipe; 1005 struct pipe_inode_info *pipe;
963 long ret, bytes; 1006 long ret, bytes;
964 loff_t out_off;
965 umode_t i_mode; 1007 umode_t i_mode;
966 int i; 1008 size_t len;
1009 int i, flags;
967 1010
968 /* 1011 /*
969 * We require the input being a regular file, as we don't want to 1012 * We require the input being a regular file, as we don't want to
@@ -999,7 +1042,13 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
999 */ 1042 */
1000 ret = 0; 1043 ret = 0;
1001 bytes = 0; 1044 bytes = 0;
1002 out_off = 0; 1045 len = sd->total_len;
1046 flags = sd->flags;
1047
1048 /*
1049 * Don't block on output, we have to drain the direct pipe.
1050 */
1051 sd->flags &= ~SPLICE_F_NONBLOCK;
1003 1052
1004 while (len) { 1053 while (len) {
1005 size_t read_len, max_read_len; 1054 size_t read_len, max_read_len;
@@ -1009,19 +1058,19 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
1009 */ 1058 */
1010 max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE)); 1059 max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE));
1011 1060
1012 ret = do_splice_to(in, ppos, pipe, max_read_len, flags); 1061 ret = do_splice_to(in, &sd->pos, pipe, max_read_len, flags);
1013 if (unlikely(ret < 0)) 1062 if (unlikely(ret < 0))
1014 goto out_release; 1063 goto out_release;
1015 1064
1016 read_len = ret; 1065 read_len = ret;
1066 sd->total_len = read_len;
1017 1067
1018 /* 1068 /*
1019 * NOTE: nonblocking mode only applies to the input. We 1069 * NOTE: nonblocking mode only applies to the input. We
1020 * must not do the output in nonblocking mode as then we 1070 * must not do the output in nonblocking mode as then we
1021 * could get stuck data in the internal pipe: 1071 * could get stuck data in the internal pipe:
1022 */ 1072 */
1023 ret = do_splice_from(pipe, out, &out_off, read_len, 1073 ret = actor(pipe, sd);
1024 flags & ~SPLICE_F_NONBLOCK);
1025 if (unlikely(ret < 0)) 1074 if (unlikely(ret < 0))
1026 goto out_release; 1075 goto out_release;
1027 1076
@@ -1066,6 +1115,48 @@ out_release:
1066 return bytes; 1115 return bytes;
1067 1116
1068 return ret; 1117 return ret;
1118
1119}
1120EXPORT_SYMBOL(splice_direct_to_actor);
1121
1122static int direct_splice_actor(struct pipe_inode_info *pipe,
1123 struct splice_desc *sd)
1124{
1125 struct file *file = sd->u.file;
1126
1127 return do_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags);
1128}
1129
1130/**
1131 * do_splice_direct - splices data directly between two files
1132 * @in: file to splice from
1133 * @ppos: input file offset
1134 * @out: file to splice to
1135 * @len: number of bytes to splice
1136 * @flags: splice modifier flags
1137 *
1138 * Description:
1139 * For use by do_sendfile(). splice can easily emulate sendfile, but
1140 * doing it in the application would incur an extra system call
1141 * (splice in + splice out, as compared to just sendfile()). So this helper
1142 * can splice directly through a process-private pipe.
1143 *
1144 */
1145long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
1146 size_t len, unsigned int flags)
1147{
1148 struct splice_desc sd = {
1149 .len = len,
1150 .total_len = len,
1151 .flags = flags,
1152 .pos = *ppos,
1153 .u.file = out,
1154 };
1155 size_t ret;
1156
1157 ret = splice_direct_to_actor(in, &sd, direct_splice_actor);
1158 *ppos = sd.pos;
1159 return ret;
1069} 1160}
1070 1161
1071/* 1162/*
@@ -1248,28 +1339,131 @@ static int get_iovec_page_array(const struct iovec __user *iov,
1248 return error; 1339 return error;
1249} 1340}
1250 1341
1342static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
1343 struct splice_desc *sd)
1344{
1345 char *src;
1346 int ret;
1347
1348 ret = buf->ops->confirm(pipe, buf);
1349 if (unlikely(ret))
1350 return ret;
1351
1352 /*
1353 * See if we can use the atomic maps, by prefaulting in the
1354 * pages and doing an atomic copy
1355 */
1356 if (!fault_in_pages_writeable(sd->u.userptr, sd->len)) {
1357 src = buf->ops->map(pipe, buf, 1);
1358 ret = __copy_to_user_inatomic(sd->u.userptr, src + buf->offset,
1359 sd->len);
1360 buf->ops->unmap(pipe, buf, src);
1361 if (!ret) {
1362 ret = sd->len;
1363 goto out;
1364 }
1365 }
1366
1367 /*
1368 * No dice, use slow non-atomic map and copy
1369 */
1370 src = buf->ops->map(pipe, buf, 0);
1371
1372 ret = sd->len;
1373 if (copy_to_user(sd->u.userptr, src + buf->offset, sd->len))
1374 ret = -EFAULT;
1375
1376out:
1377 if (ret > 0)
1378 sd->u.userptr += ret;
1379 buf->ops->unmap(pipe, buf, src);
1380 return ret;
1381}
1382
1383/*
1384 * For lack of a better implementation, implement vmsplice() to userspace
1385 * as a simple copy of the pipes pages to the user iov.
1386 */
1387static long vmsplice_to_user(struct file *file, const struct iovec __user *iov,
1388 unsigned long nr_segs, unsigned int flags)
1389{
1390 struct pipe_inode_info *pipe;
1391 struct splice_desc sd;
1392 ssize_t size;
1393 int error;
1394 long ret;
1395
1396 pipe = pipe_info(file->f_path.dentry->d_inode);
1397 if (!pipe)
1398 return -EBADF;
1399
1400 if (pipe->inode)
1401 mutex_lock(&pipe->inode->i_mutex);
1402
1403 error = ret = 0;
1404 while (nr_segs) {
1405 void __user *base;
1406 size_t len;
1407
1408 /*
1409 * Get user address base and length for this iovec.
1410 */
1411 error = get_user(base, &iov->iov_base);
1412 if (unlikely(error))
1413 break;
1414 error = get_user(len, &iov->iov_len);
1415 if (unlikely(error))
1416 break;
1417
1418 /*
1419 * Sanity check this iovec. 0 read succeeds.
1420 */
1421 if (unlikely(!len))
1422 break;
1423 if (unlikely(!base)) {
1424 error = -EFAULT;
1425 break;
1426 }
1427
1428 sd.len = 0;
1429 sd.total_len = len;
1430 sd.flags = flags;
1431 sd.u.userptr = base;
1432 sd.pos = 0;
1433
1434 size = __splice_from_pipe(pipe, &sd, pipe_to_user);
1435 if (size < 0) {
1436 if (!ret)
1437 ret = size;
1438
1439 break;
1440 }
1441
1442 ret += size;
1443
1444 if (size < len)
1445 break;
1446
1447 nr_segs--;
1448 iov++;
1449 }
1450
1451 if (pipe->inode)
1452 mutex_unlock(&pipe->inode->i_mutex);
1453
1454 if (!ret)
1455 ret = error;
1456
1457 return ret;
1458}
1459
1251/* 1460/*
1252 * vmsplice splices a user address range into a pipe. It can be thought of 1461 * vmsplice splices a user address range into a pipe. It can be thought of
1253 * as splice-from-memory, where the regular splice is splice-from-file (or 1462 * as splice-from-memory, where the regular splice is splice-from-file (or
1254 * to file). In both cases the output is a pipe, naturally. 1463 * to file). In both cases the output is a pipe, naturally.
1255 *
1256 * Note that vmsplice only supports splicing _from_ user memory to a pipe,
1257 * not the other way around. Splicing from user memory is a simple operation
1258 * that can be supported without any funky alignment restrictions or nasty
1259 * vm tricks. We simply map in the user memory and fill them into a pipe.
1260 * The reverse isn't quite as easy, though. There are two possible solutions
1261 * for that:
1262 *
1263 * - memcpy() the data internally, at which point we might as well just
1264 * do a regular read() on the buffer anyway.
1265 * - Lots of nasty vm tricks, that are neither fast nor flexible (it
1266 * has restriction limitations on both ends of the pipe).
1267 *
1268 * Alas, it isn't here.
1269 *
1270 */ 1464 */
1271static long do_vmsplice(struct file *file, const struct iovec __user *iov, 1465static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
1272 unsigned long nr_segs, unsigned int flags) 1466 unsigned long nr_segs, unsigned int flags)
1273{ 1467{
1274 struct pipe_inode_info *pipe; 1468 struct pipe_inode_info *pipe;
1275 struct page *pages[PIPE_BUFFERS]; 1469 struct page *pages[PIPE_BUFFERS];
@@ -1284,10 +1478,6 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov,
1284 pipe = pipe_info(file->f_path.dentry->d_inode); 1478 pipe = pipe_info(file->f_path.dentry->d_inode);
1285 if (!pipe) 1479 if (!pipe)
1286 return -EBADF; 1480 return -EBADF;
1287 if (unlikely(nr_segs > UIO_MAXIOV))
1288 return -EINVAL;
1289 else if (unlikely(!nr_segs))
1290 return 0;
1291 1481
1292 spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial, 1482 spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial,
1293 flags & SPLICE_F_GIFT); 1483 flags & SPLICE_F_GIFT);
@@ -1297,6 +1487,22 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov,
1297 return splice_to_pipe(pipe, &spd); 1487 return splice_to_pipe(pipe, &spd);
1298} 1488}
1299 1489
1490/*
1491 * Note that vmsplice only really supports true splicing _from_ user memory
1492 * to a pipe, not the other way around. Splicing from user memory is a simple
1493 * operation that can be supported without any funky alignment restrictions
1494 * or nasty vm tricks. We simply map in the user memory and fill them into
1495 * a pipe. The reverse isn't quite as easy, though. There are two possible
1496 * solutions for that:
1497 *
1498 * - memcpy() the data internally, at which point we might as well just
1499 * do a regular read() on the buffer anyway.
1500 * - Lots of nasty vm tricks, that are neither fast nor flexible (it
1501 * has restriction limitations on both ends of the pipe).
1502 *
1503 * Currently we punt and implement it as a normal copy, see pipe_to_user().
1504 *
1505 */
1300asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, 1506asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov,
1301 unsigned long nr_segs, unsigned int flags) 1507 unsigned long nr_segs, unsigned int flags)
1302{ 1508{
@@ -1304,11 +1510,18 @@ asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov,
1304 long error; 1510 long error;
1305 int fput; 1511 int fput;
1306 1512
1513 if (unlikely(nr_segs > UIO_MAXIOV))
1514 return -EINVAL;
1515 else if (unlikely(!nr_segs))
1516 return 0;
1517
1307 error = -EBADF; 1518 error = -EBADF;
1308 file = fget_light(fd, &fput); 1519 file = fget_light(fd, &fput);
1309 if (file) { 1520 if (file) {
1310 if (file->f_mode & FMODE_WRITE) 1521 if (file->f_mode & FMODE_WRITE)
1311 error = do_vmsplice(file, iov, nr_segs, flags); 1522 error = vmsplice_to_pipe(file, iov, nr_segs, flags);
1523 else if (file->f_mode & FMODE_READ)
1524 error = vmsplice_to_user(file, iov, nr_segs, flags);
1312 1525
1313 fput_light(file, fput); 1526 fput_light(file, fput);
1314 } 1527 }
diff --git a/fs/sysv/file.c b/fs/sysv/file.c
index 0732ddb9020b..589be21d884e 100644
--- a/fs/sysv/file.c
+++ b/fs/sysv/file.c
@@ -27,7 +27,7 @@ const struct file_operations sysv_file_operations = {
27 .aio_write = generic_file_aio_write, 27 .aio_write = generic_file_aio_write,
28 .mmap = generic_file_mmap, 28 .mmap = generic_file_mmap,
29 .fsync = sysv_sync_file, 29 .fsync = sysv_sync_file,
30 .sendfile = generic_file_sendfile, 30 .splice_read = generic_file_splice_read,
31}; 31};
32 32
33const struct inode_operations sysv_file_inode_operations = { 33const struct inode_operations sysv_file_inode_operations = {
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 51b5764685e7..df070bee8d4f 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -261,7 +261,7 @@ const struct file_operations udf_file_operations = {
261 .aio_write = udf_file_aio_write, 261 .aio_write = udf_file_aio_write,
262 .release = udf_release_file, 262 .release = udf_release_file,
263 .fsync = udf_fsync_file, 263 .fsync = udf_fsync_file,
264 .sendfile = generic_file_sendfile, 264 .splice_read = generic_file_splice_read,
265}; 265};
266 266
267const struct inode_operations udf_file_inode_operations = { 267const struct inode_operations udf_file_inode_operations = {
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index 1e096323bad4..6705d74c6d2d 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -60,5 +60,5 @@ const struct file_operations ufs_file_operations = {
60 .mmap = generic_file_mmap, 60 .mmap = generic_file_mmap,
61 .open = generic_file_open, 61 .open = generic_file_open,
62 .fsync = ufs_sync_file, 62 .fsync = ufs_sync_file,
63 .sendfile = generic_file_sendfile, 63 .splice_read = generic_file_splice_read,
64}; 64};
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index cb51dc961355..8c43cd2e237a 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -124,30 +124,6 @@ xfs_file_aio_write_invis(
124} 124}
125 125
126STATIC ssize_t 126STATIC ssize_t
127xfs_file_sendfile(
128 struct file *filp,
129 loff_t *pos,
130 size_t count,
131 read_actor_t actor,
132 void *target)
133{
134 return bhv_vop_sendfile(vn_from_inode(filp->f_path.dentry->d_inode),
135 filp, pos, 0, count, actor, target, NULL);
136}
137
138STATIC ssize_t
139xfs_file_sendfile_invis(
140 struct file *filp,
141 loff_t *pos,
142 size_t count,
143 read_actor_t actor,
144 void *target)
145{
146 return bhv_vop_sendfile(vn_from_inode(filp->f_path.dentry->d_inode),
147 filp, pos, IO_INVIS, count, actor, target, NULL);
148}
149
150STATIC ssize_t
151xfs_file_splice_read( 127xfs_file_splice_read(
152 struct file *infilp, 128 struct file *infilp,
153 loff_t *ppos, 129 loff_t *ppos,
@@ -452,7 +428,6 @@ const struct file_operations xfs_file_operations = {
452 .write = do_sync_write, 428 .write = do_sync_write,
453 .aio_read = xfs_file_aio_read, 429 .aio_read = xfs_file_aio_read,
454 .aio_write = xfs_file_aio_write, 430 .aio_write = xfs_file_aio_write,
455 .sendfile = xfs_file_sendfile,
456 .splice_read = xfs_file_splice_read, 431 .splice_read = xfs_file_splice_read,
457 .splice_write = xfs_file_splice_write, 432 .splice_write = xfs_file_splice_write,
458 .unlocked_ioctl = xfs_file_ioctl, 433 .unlocked_ioctl = xfs_file_ioctl,
@@ -475,7 +450,6 @@ const struct file_operations xfs_invis_file_operations = {
475 .write = do_sync_write, 450 .write = do_sync_write,
476 .aio_read = xfs_file_aio_read_invis, 451 .aio_read = xfs_file_aio_read_invis,
477 .aio_write = xfs_file_aio_write_invis, 452 .aio_write = xfs_file_aio_write_invis,
478 .sendfile = xfs_file_sendfile_invis,
479 .splice_read = xfs_file_splice_read_invis, 453 .splice_read = xfs_file_splice_read_invis,
480 .splice_write = xfs_file_splice_write_invis, 454 .splice_write = xfs_file_splice_write_invis,
481 .unlocked_ioctl = xfs_file_ioctl_invis, 455 .unlocked_ioctl = xfs_file_ioctl_invis,
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 715adad7dd4d..af24a457d3a3 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -101,7 +101,6 @@
101 * Feature macros (disable/enable) 101 * Feature macros (disable/enable)
102 */ 102 */
103#undef HAVE_REFCACHE /* reference cache not needed for NFS in 2.6 */ 103#undef HAVE_REFCACHE /* reference cache not needed for NFS in 2.6 */
104#define HAVE_SENDFILE /* sendfile(2) exists in 2.6, but not in 2.4 */
105#define HAVE_SPLICE /* a splice(2) exists in 2.6, but not in 2.4 */ 104#define HAVE_SPLICE /* a splice(2) exists in 2.6, but not in 2.4 */
106#ifdef CONFIG_SMP 105#ifdef CONFIG_SMP
107#define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */ 106#define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index ed90403f0ee7..765ec16a6e39 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -287,50 +287,6 @@ xfs_read(
287} 287}
288 288
289ssize_t 289ssize_t
290xfs_sendfile(
291 bhv_desc_t *bdp,
292 struct file *filp,
293 loff_t *offset,
294 int ioflags,
295 size_t count,
296 read_actor_t actor,
297 void *target,
298 cred_t *credp)
299{
300 xfs_inode_t *ip = XFS_BHVTOI(bdp);
301 xfs_mount_t *mp = ip->i_mount;
302 ssize_t ret;
303
304 XFS_STATS_INC(xs_read_calls);
305 if (XFS_FORCED_SHUTDOWN(mp))
306 return -EIO;
307
308 xfs_ilock(ip, XFS_IOLOCK_SHARED);
309
310 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
311 (!(ioflags & IO_INVIS))) {
312 bhv_vrwlock_t locktype = VRWLOCK_READ;
313 int error;
314
315 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
316 *offset, count,
317 FILP_DELAY_FLAG(filp), &locktype);
318 if (error) {
319 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
320 return -error;
321 }
322 }
323 xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore,
324 (void *)(unsigned long)target, count, *offset, ioflags);
325 ret = generic_file_sendfile(filp, offset, count, actor, target);
326 if (ret > 0)
327 XFS_STATS_ADD(xs_read_bytes, ret);
328
329 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
330 return ret;
331}
332
333ssize_t
334xfs_splice_read( 290xfs_splice_read(
335 bhv_desc_t *bdp, 291 bhv_desc_t *bdp,
336 struct file *infilp, 292 struct file *infilp,
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index 7ac51b1d2161..7c60a1eed88b 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -90,9 +90,6 @@ extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
90extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *, 90extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *,
91 const struct iovec *, unsigned int, 91 const struct iovec *, unsigned int,
92 loff_t *, int, struct cred *); 92 loff_t *, int, struct cred *);
93extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *,
94 loff_t *, int, size_t, read_actor_t,
95 void *, struct cred *);
96extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, loff_t *, 93extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, loff_t *,
97 struct pipe_inode_info *, size_t, int, int, 94 struct pipe_inode_info *, size_t, int, int,
98 struct cred *); 95 struct cred *);
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index d1b2d01843d1..013048a92643 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -139,9 +139,6 @@ typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
139typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *, 139typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *,
140 const struct iovec *, unsigned int, 140 const struct iovec *, unsigned int,
141 loff_t *, int, struct cred *); 141 loff_t *, int, struct cred *);
142typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *,
143 loff_t *, int, size_t, read_actor_t,
144 void *, struct cred *);
145typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, loff_t *, 142typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, loff_t *,
146 struct pipe_inode_info *, size_t, int, int, 143 struct pipe_inode_info *, size_t, int, int,
147 struct cred *); 144 struct cred *);
@@ -206,7 +203,6 @@ typedef struct bhv_vnodeops {
206 vop_close_t vop_close; 203 vop_close_t vop_close;
207 vop_read_t vop_read; 204 vop_read_t vop_read;
208 vop_write_t vop_write; 205 vop_write_t vop_write;
209 vop_sendfile_t vop_sendfile;
210 vop_splice_read_t vop_splice_read; 206 vop_splice_read_t vop_splice_read;
211 vop_splice_write_t vop_splice_write; 207 vop_splice_write_t vop_splice_write;
212 vop_ioctl_t vop_ioctl; 208 vop_ioctl_t vop_ioctl;
@@ -254,8 +250,6 @@ typedef struct bhv_vnodeops {
254 VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr) 250 VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
255#define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \ 251#define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \
256 VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr) 252 VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
257#define bhv_vop_sendfile(vp,f,off,ioflags,cnt,act,targ,cr) \
258 VOP(vop_sendfile, vp)(VNHEAD(vp),f,off,ioflags,cnt,act,targ,cr)
259#define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \ 253#define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \
260 VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr) 254 VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
261#define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \ 255#define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index de17aed578f0..70bc82f65311 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -4680,9 +4680,6 @@ bhv_vnodeops_t xfs_vnodeops = {
4680 .vop_open = xfs_open, 4680 .vop_open = xfs_open,
4681 .vop_close = xfs_close, 4681 .vop_close = xfs_close,
4682 .vop_read = xfs_read, 4682 .vop_read = xfs_read,
4683#ifdef HAVE_SENDFILE
4684 .vop_sendfile = xfs_sendfile,
4685#endif
4686#ifdef HAVE_SPLICE 4683#ifdef HAVE_SPLICE
4687 .vop_splice_read = xfs_splice_read, 4684 .vop_splice_read = xfs_splice_read,
4688 .vop_splice_write = xfs_splice_write, 4685 .vop_splice_write = xfs_splice_write,