diff options
-rw-r--r-- | fs/block_dev.c | 2 | ||||
-rw-r--r-- | fs/exofs/file.c | 2 | ||||
-rw-r--r-- | fs/ext2/file.c | 2 | ||||
-rw-r--r-- | fs/ext3/file.c | 2 | ||||
-rw-r--r-- | fs/ext4/file.c | 2 | ||||
-rw-r--r-- | fs/f2fs/file.c | 2 | ||||
-rw-r--r-- | fs/gfs2/file.c | 4 | ||||
-rw-r--r-- | fs/jfs/file.c | 2 | ||||
-rw-r--r-- | fs/ramfs/file-mmu.c | 2 | ||||
-rw-r--r-- | fs/ramfs/file-nommu.c | 2 | ||||
-rw-r--r-- | fs/reiserfs/file.c | 2 | ||||
-rw-r--r-- | fs/splice.c | 140 | ||||
-rw-r--r-- | fs/ubifs/file.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_file.c | 43 | ||||
-rw-r--r-- | fs/xfs/xfs_trace.h | 1 | ||||
-rw-r--r-- | include/linux/fs.h | 2 |
16 files changed, 156 insertions, 56 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 4e36b8ea8aa4..e68e150b1b16 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -1583,7 +1583,7 @@ const struct file_operations def_blk_fops = { | |||
1583 | .compat_ioctl = compat_blkdev_ioctl, | 1583 | .compat_ioctl = compat_blkdev_ioctl, |
1584 | #endif | 1584 | #endif |
1585 | .splice_read = generic_file_splice_read, | 1585 | .splice_read = generic_file_splice_read, |
1586 | .splice_write = generic_file_splice_write, | 1586 | .splice_write = iter_file_splice_write, |
1587 | }; | 1587 | }; |
1588 | 1588 | ||
1589 | int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) | 1589 | int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) |
diff --git a/fs/exofs/file.c b/fs/exofs/file.c index 5b7f6be5a2d5..71bf8e4fb5d4 100644 --- a/fs/exofs/file.c +++ b/fs/exofs/file.c | |||
@@ -77,7 +77,7 @@ const struct file_operations exofs_file_operations = { | |||
77 | .fsync = exofs_file_fsync, | 77 | .fsync = exofs_file_fsync, |
78 | .flush = exofs_flush, | 78 | .flush = exofs_flush, |
79 | .splice_read = generic_file_splice_read, | 79 | .splice_read = generic_file_splice_read, |
80 | .splice_write = generic_file_splice_write, | 80 | .splice_write = iter_file_splice_write, |
81 | }; | 81 | }; |
82 | 82 | ||
83 | const struct inode_operations exofs_file_inode_operations = { | 83 | const struct inode_operations exofs_file_inode_operations = { |
diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 970c6aca15cc..7c87b22a7228 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c | |||
@@ -75,7 +75,7 @@ const struct file_operations ext2_file_operations = { | |||
75 | .release = ext2_release_file, | 75 | .release = ext2_release_file, |
76 | .fsync = ext2_fsync, | 76 | .fsync = ext2_fsync, |
77 | .splice_read = generic_file_splice_read, | 77 | .splice_read = generic_file_splice_read, |
78 | .splice_write = generic_file_splice_write, | 78 | .splice_write = iter_file_splice_write, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | #ifdef CONFIG_EXT2_FS_XIP | 81 | #ifdef CONFIG_EXT2_FS_XIP |
diff --git a/fs/ext3/file.c b/fs/ext3/file.c index c833b1226d4d..a062fa1e1b11 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c | |||
@@ -63,7 +63,7 @@ const struct file_operations ext3_file_operations = { | |||
63 | .release = ext3_release_file, | 63 | .release = ext3_release_file, |
64 | .fsync = ext3_sync_file, | 64 | .fsync = ext3_sync_file, |
65 | .splice_read = generic_file_splice_read, | 65 | .splice_read = generic_file_splice_read, |
66 | .splice_write = generic_file_splice_write, | 66 | .splice_write = iter_file_splice_write, |
67 | }; | 67 | }; |
68 | 68 | ||
69 | const struct inode_operations ext3_file_inode_operations = { | 69 | const struct inode_operations ext3_file_inode_operations = { |
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 48383a5f37a1..708aad768199 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
@@ -599,7 +599,7 @@ const struct file_operations ext4_file_operations = { | |||
599 | .release = ext4_release_file, | 599 | .release = ext4_release_file, |
600 | .fsync = ext4_sync_file, | 600 | .fsync = ext4_sync_file, |
601 | .splice_read = generic_file_splice_read, | 601 | .splice_read = generic_file_splice_read, |
602 | .splice_write = generic_file_splice_write, | 602 | .splice_write = iter_file_splice_write, |
603 | .fallocate = ext4_fallocate, | 603 | .fallocate = ext4_fallocate, |
604 | }; | 604 | }; |
605 | 605 | ||
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 22f4900dd8eb..e4ba4b93f96a 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -692,5 +692,5 @@ const struct file_operations f2fs_file_operations = { | |||
692 | .compat_ioctl = f2fs_compat_ioctl, | 692 | .compat_ioctl = f2fs_compat_ioctl, |
693 | #endif | 693 | #endif |
694 | .splice_read = generic_file_splice_read, | 694 | .splice_read = generic_file_splice_read, |
695 | .splice_write = generic_file_splice_write, | 695 | .splice_write = iter_file_splice_write, |
696 | }; | 696 | }; |
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index ca932cd358d3..01b4c5b1bff8 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -1068,7 +1068,7 @@ const struct file_operations gfs2_file_fops = { | |||
1068 | .lock = gfs2_lock, | 1068 | .lock = gfs2_lock, |
1069 | .flock = gfs2_flock, | 1069 | .flock = gfs2_flock, |
1070 | .splice_read = generic_file_splice_read, | 1070 | .splice_read = generic_file_splice_read, |
1071 | .splice_write = generic_file_splice_write, | 1071 | .splice_write = iter_file_splice_write, |
1072 | .setlease = gfs2_setlease, | 1072 | .setlease = gfs2_setlease, |
1073 | .fallocate = gfs2_fallocate, | 1073 | .fallocate = gfs2_fallocate, |
1074 | }; | 1074 | }; |
@@ -1098,7 +1098,7 @@ const struct file_operations gfs2_file_fops_nolock = { | |||
1098 | .release = gfs2_release, | 1098 | .release = gfs2_release, |
1099 | .fsync = gfs2_fsync, | 1099 | .fsync = gfs2_fsync, |
1100 | .splice_read = generic_file_splice_read, | 1100 | .splice_read = generic_file_splice_read, |
1101 | .splice_write = generic_file_splice_write, | 1101 | .splice_write = iter_file_splice_write, |
1102 | .setlease = generic_setlease, | 1102 | .setlease = generic_setlease, |
1103 | .fallocate = gfs2_fallocate, | 1103 | .fallocate = gfs2_fallocate, |
1104 | }; | 1104 | }; |
diff --git a/fs/jfs/file.c b/fs/jfs/file.c index cc744ecaf51f..33aa0cc1f8b8 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c | |||
@@ -157,7 +157,7 @@ const struct file_operations jfs_file_operations = { | |||
157 | .write_iter = generic_file_write_iter, | 157 | .write_iter = generic_file_write_iter, |
158 | .mmap = generic_file_mmap, | 158 | .mmap = generic_file_mmap, |
159 | .splice_read = generic_file_splice_read, | 159 | .splice_read = generic_file_splice_read, |
160 | .splice_write = generic_file_splice_write, | 160 | .splice_write = iter_file_splice_write, |
161 | .fsync = jfs_fsync, | 161 | .fsync = jfs_fsync, |
162 | .release = jfs_release, | 162 | .release = jfs_release, |
163 | .unlocked_ioctl = jfs_ioctl, | 163 | .unlocked_ioctl = jfs_ioctl, |
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c index 6ea0b9718a9d..4f56de822d2f 100644 --- a/fs/ramfs/file-mmu.c +++ b/fs/ramfs/file-mmu.c | |||
@@ -38,7 +38,7 @@ const struct file_operations ramfs_file_operations = { | |||
38 | .mmap = generic_file_mmap, | 38 | .mmap = generic_file_mmap, |
39 | .fsync = noop_fsync, | 39 | .fsync = noop_fsync, |
40 | .splice_read = generic_file_splice_read, | 40 | .splice_read = generic_file_splice_read, |
41 | .splice_write = generic_file_splice_write, | 41 | .splice_write = iter_file_splice_write, |
42 | .llseek = generic_file_llseek, | 42 | .llseek = generic_file_llseek, |
43 | }; | 43 | }; |
44 | 44 | ||
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 9ed420f8f3ca..dda012ad4208 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c | |||
@@ -43,7 +43,7 @@ const struct file_operations ramfs_file_operations = { | |||
43 | .write_iter = generic_file_write_iter, | 43 | .write_iter = generic_file_write_iter, |
44 | .fsync = noop_fsync, | 44 | .fsync = noop_fsync, |
45 | .splice_read = generic_file_splice_read, | 45 | .splice_read = generic_file_splice_read, |
46 | .splice_write = generic_file_splice_write, | 46 | .splice_write = iter_file_splice_write, |
47 | .llseek = generic_file_llseek, | 47 | .llseek = generic_file_llseek, |
48 | }; | 48 | }; |
49 | 49 | ||
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 7c8ecd6468db..f070cc827456 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
@@ -248,7 +248,7 @@ const struct file_operations reiserfs_file_operations = { | |||
248 | .read_iter = generic_file_read_iter, | 248 | .read_iter = generic_file_read_iter, |
249 | .write_iter = generic_file_write_iter, | 249 | .write_iter = generic_file_write_iter, |
250 | .splice_read = generic_file_splice_read, | 250 | .splice_read = generic_file_splice_read, |
251 | .splice_write = generic_file_splice_write, | 251 | .splice_write = iter_file_splice_write, |
252 | .llseek = generic_file_llseek, | 252 | .llseek = generic_file_llseek, |
253 | }; | 253 | }; |
254 | 254 | ||
diff --git a/fs/splice.c b/fs/splice.c index f99e420744c7..f195a9b89fb2 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/gfp.h> | 32 | #include <linux/gfp.h> |
33 | #include <linux/socket.h> | 33 | #include <linux/socket.h> |
34 | #include <linux/compat.h> | 34 | #include <linux/compat.h> |
35 | #include <linux/aio.h> | ||
35 | #include "internal.h" | 36 | #include "internal.h" |
36 | 37 | ||
37 | /* | 38 | /* |
@@ -1052,6 +1053,145 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
1052 | 1053 | ||
1053 | EXPORT_SYMBOL(generic_file_splice_write); | 1054 | EXPORT_SYMBOL(generic_file_splice_write); |
1054 | 1055 | ||
1056 | /** | ||
1057 | * iter_file_splice_write - splice data from a pipe to a file | ||
1058 | * @pipe: pipe info | ||
1059 | * @out: file to write to | ||
1060 | * @ppos: position in @out | ||
1061 | * @len: number of bytes to splice | ||
1062 | * @flags: splice modifier flags | ||
1063 | * | ||
1064 | * Description: | ||
1065 | * Will either move or copy pages (determined by @flags options) from | ||
1066 | * the given pipe inode to the given file. | ||
1067 | * This one is ->write_iter-based. | ||
1068 | * | ||
1069 | */ | ||
1070 | ssize_t | ||
1071 | iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | ||
1072 | loff_t *ppos, size_t len, unsigned int flags) | ||
1073 | { | ||
1074 | struct splice_desc sd = { | ||
1075 | .total_len = len, | ||
1076 | .flags = flags, | ||
1077 | .pos = *ppos, | ||
1078 | .u.file = out, | ||
1079 | }; | ||
1080 | int nbufs = pipe->buffers; | ||
1081 | struct bio_vec *array = kcalloc(nbufs, sizeof(struct bio_vec), | ||
1082 | GFP_KERNEL); | ||
1083 | ssize_t ret; | ||
1084 | |||
1085 | if (unlikely(!array)) | ||
1086 | return -ENOMEM; | ||
1087 | |||
1088 | pipe_lock(pipe); | ||
1089 | |||
1090 | splice_from_pipe_begin(&sd); | ||
1091 | while (sd.total_len) { | ||
1092 | struct iov_iter from; | ||
1093 | struct kiocb kiocb; | ||
1094 | size_t left; | ||
1095 | int n, idx; | ||
1096 | |||
1097 | ret = splice_from_pipe_next(pipe, &sd); | ||
1098 | if (ret <= 0) | ||
1099 | break; | ||
1100 | |||
1101 | if (unlikely(nbufs < pipe->buffers)) { | ||
1102 | kfree(array); | ||
1103 | nbufs = pipe->buffers; | ||
1104 | array = kcalloc(nbufs, sizeof(struct bio_vec), | ||
1105 | GFP_KERNEL); | ||
1106 | if (!array) { | ||
1107 | ret = -ENOMEM; | ||
1108 | break; | ||
1109 | } | ||
1110 | } | ||
1111 | |||
1112 | /* build the vector */ | ||
1113 | left = sd.total_len; | ||
1114 | for (n = 0, idx = pipe->curbuf; left && n < pipe->nrbufs; n++, idx++) { | ||
1115 | struct pipe_buffer *buf = pipe->bufs + idx; | ||
1116 | size_t this_len = buf->len; | ||
1117 | |||
1118 | if (this_len > left) | ||
1119 | this_len = left; | ||
1120 | |||
1121 | if (idx == pipe->buffers - 1) | ||
1122 | idx = -1; | ||
1123 | |||
1124 | ret = buf->ops->confirm(pipe, buf); | ||
1125 | if (unlikely(ret)) { | ||
1126 | if (ret == -ENODATA) | ||
1127 | ret = 0; | ||
1128 | goto done; | ||
1129 | } | ||
1130 | |||
1131 | array[n].bv_page = buf->page; | ||
1132 | array[n].bv_len = this_len; | ||
1133 | array[n].bv_offset = buf->offset; | ||
1134 | left -= this_len; | ||
1135 | } | ||
1136 | |||
1137 | /* ... iov_iter */ | ||
1138 | from.type = ITER_BVEC | WRITE; | ||
1139 | from.bvec = array; | ||
1140 | from.nr_segs = n; | ||
1141 | from.count = sd.total_len - left; | ||
1142 | from.iov_offset = 0; | ||
1143 | |||
1144 | /* ... and iocb */ | ||
1145 | init_sync_kiocb(&kiocb, out); | ||
1146 | kiocb.ki_pos = sd.pos; | ||
1147 | kiocb.ki_nbytes = sd.total_len - left; | ||
1148 | |||
1149 | /* now, send it */ | ||
1150 | ret = out->f_op->write_iter(&kiocb, &from); | ||
1151 | if (-EIOCBQUEUED == ret) | ||
1152 | ret = wait_on_sync_kiocb(&kiocb); | ||
1153 | |||
1154 | if (ret <= 0) | ||
1155 | break; | ||
1156 | |||
1157 | sd.num_spliced += ret; | ||
1158 | sd.total_len -= ret; | ||
1159 | *ppos = sd.pos = kiocb.ki_pos; | ||
1160 | |||
1161 | /* dismiss the fully eaten buffers, adjust the partial one */ | ||
1162 | while (ret) { | ||
1163 | struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; | ||
1164 | if (ret >= buf->len) { | ||
1165 | const struct pipe_buf_operations *ops = buf->ops; | ||
1166 | ret -= buf->len; | ||
1167 | buf->len = 0; | ||
1168 | buf->ops = NULL; | ||
1169 | ops->release(pipe, buf); | ||
1170 | pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); | ||
1171 | pipe->nrbufs--; | ||
1172 | if (pipe->files) | ||
1173 | sd.need_wakeup = true; | ||
1174 | } else { | ||
1175 | buf->offset += ret; | ||
1176 | buf->len -= ret; | ||
1177 | ret = 0; | ||
1178 | } | ||
1179 | } | ||
1180 | } | ||
1181 | done: | ||
1182 | kfree(array); | ||
1183 | splice_from_pipe_end(pipe, &sd); | ||
1184 | |||
1185 | pipe_unlock(pipe); | ||
1186 | |||
1187 | if (sd.num_spliced) | ||
1188 | ret = sd.num_spliced; | ||
1189 | |||
1190 | return ret; | ||
1191 | } | ||
1192 | |||
1193 | EXPORT_SYMBOL(iter_file_splice_write); | ||
1194 | |||
1055 | static int write_pipe_buf(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | 1195 | static int write_pipe_buf(struct pipe_inode_info *pipe, struct pipe_buffer *buf, |
1056 | struct splice_desc *sd) | 1196 | struct splice_desc *sd) |
1057 | { | 1197 | { |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 6bc4e8efbccf..0888502a6041 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -1585,7 +1585,7 @@ const struct file_operations ubifs_file_operations = { | |||
1585 | .fsync = ubifs_fsync, | 1585 | .fsync = ubifs_fsync, |
1586 | .unlocked_ioctl = ubifs_ioctl, | 1586 | .unlocked_ioctl = ubifs_ioctl, |
1587 | .splice_read = generic_file_splice_read, | 1587 | .splice_read = generic_file_splice_read, |
1588 | .splice_write = generic_file_splice_write, | 1588 | .splice_write = iter_file_splice_write, |
1589 | #ifdef CONFIG_COMPAT | 1589 | #ifdef CONFIG_COMPAT |
1590 | .compat_ioctl = ubifs_compat_ioctl, | 1590 | .compat_ioctl = ubifs_compat_ioctl, |
1591 | #endif | 1591 | #endif |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 5446e86d3485..b1c489c1fb2e 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -343,47 +343,6 @@ xfs_file_splice_read( | |||
343 | } | 343 | } |
344 | 344 | ||
345 | /* | 345 | /* |
346 | * xfs_file_splice_write() does not use xfs_rw_ilock() because | ||
347 | * generic_file_splice_write() takes the i_mutex itself. This, in theory, | ||
348 | * couuld cause lock inversions between the aio_write path and the splice path | ||
349 | * if someone is doing concurrent splice(2) based writes and write(2) based | ||
350 | * writes to the same inode. The only real way to fix this is to re-implement | ||
351 | * the generic code here with correct locking orders. | ||
352 | */ | ||
353 | STATIC ssize_t | ||
354 | xfs_file_splice_write( | ||
355 | struct pipe_inode_info *pipe, | ||
356 | struct file *outfilp, | ||
357 | loff_t *ppos, | ||
358 | size_t count, | ||
359 | unsigned int flags) | ||
360 | { | ||
361 | struct inode *inode = outfilp->f_mapping->host; | ||
362 | struct xfs_inode *ip = XFS_I(inode); | ||
363 | int ioflags = 0; | ||
364 | ssize_t ret; | ||
365 | |||
366 | XFS_STATS_INC(xs_write_calls); | ||
367 | |||
368 | if (outfilp->f_mode & FMODE_NOCMTIME) | ||
369 | ioflags |= IO_INVIS; | ||
370 | |||
371 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | ||
372 | return -EIO; | ||
373 | |||
374 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
375 | |||
376 | trace_xfs_file_splice_write(ip, count, *ppos, ioflags); | ||
377 | |||
378 | ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); | ||
379 | if (ret > 0) | ||
380 | XFS_STATS_ADD(xs_write_bytes, ret); | ||
381 | |||
382 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
383 | return ret; | ||
384 | } | ||
385 | |||
386 | /* | ||
387 | * This routine is called to handle zeroing any space in the last block of the | 346 | * This routine is called to handle zeroing any space in the last block of the |
388 | * file that is beyond the EOF. We do this since the size is being increased | 347 | * file that is beyond the EOF. We do this since the size is being increased |
389 | * without writing anything to that block and we don't want to read the | 348 | * without writing anything to that block and we don't want to read the |
@@ -1442,7 +1401,7 @@ const struct file_operations xfs_file_operations = { | |||
1442 | .read_iter = xfs_file_read_iter, | 1401 | .read_iter = xfs_file_read_iter, |
1443 | .write_iter = xfs_file_write_iter, | 1402 | .write_iter = xfs_file_write_iter, |
1444 | .splice_read = xfs_file_splice_read, | 1403 | .splice_read = xfs_file_splice_read, |
1445 | .splice_write = xfs_file_splice_write, | 1404 | .splice_write = iter_file_splice_write, |
1446 | .unlocked_ioctl = xfs_file_ioctl, | 1405 | .unlocked_ioctl = xfs_file_ioctl, |
1447 | #ifdef CONFIG_COMPAT | 1406 | #ifdef CONFIG_COMPAT |
1448 | .compat_ioctl = xfs_file_compat_ioctl, | 1407 | .compat_ioctl = xfs_file_compat_ioctl, |
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 65d8c793a25c..53182f97cf01 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h | |||
@@ -1060,7 +1060,6 @@ DEFINE_RW_EVENT(xfs_file_read); | |||
1060 | DEFINE_RW_EVENT(xfs_file_buffered_write); | 1060 | DEFINE_RW_EVENT(xfs_file_buffered_write); |
1061 | DEFINE_RW_EVENT(xfs_file_direct_write); | 1061 | DEFINE_RW_EVENT(xfs_file_direct_write); |
1062 | DEFINE_RW_EVENT(xfs_file_splice_read); | 1062 | DEFINE_RW_EVENT(xfs_file_splice_read); |
1063 | DEFINE_RW_EVENT(xfs_file_splice_write); | ||
1064 | 1063 | ||
1065 | DECLARE_EVENT_CLASS(xfs_page_class, | 1064 | DECLARE_EVENT_CLASS(xfs_page_class, |
1066 | TP_PROTO(struct inode *inode, struct page *page, unsigned long off, | 1065 | TP_PROTO(struct inode *inode, struct page *page, unsigned long off, |
diff --git a/include/linux/fs.h b/include/linux/fs.h index a6448849dbce..8bd8ed357c7b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -2434,6 +2434,8 @@ extern ssize_t default_file_splice_read(struct file *, loff_t *, | |||
2434 | struct pipe_inode_info *, size_t, unsigned int); | 2434 | struct pipe_inode_info *, size_t, unsigned int); |
2435 | extern ssize_t generic_file_splice_write(struct pipe_inode_info *, | 2435 | extern ssize_t generic_file_splice_write(struct pipe_inode_info *, |
2436 | struct file *, loff_t *, size_t, unsigned int); | 2436 | struct file *, loff_t *, size_t, unsigned int); |
2437 | extern ssize_t iter_file_splice_write(struct pipe_inode_info *, | ||
2438 | struct file *, loff_t *, size_t, unsigned int); | ||
2437 | extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, | 2439 | extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, |
2438 | struct file *out, loff_t *, size_t len, unsigned int flags); | 2440 | struct file *out, loff_t *, size_t len, unsigned int flags); |
2439 | 2441 | ||