diff options
Diffstat (limited to 'fs/splice.c')
| -rw-r--r-- | fs/splice.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/fs/splice.c b/fs/splice.c index d37431dd60a1..3b7ee656f3aa 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
| @@ -1098,27 +1098,13 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, | |||
| 1098 | { | 1098 | { |
| 1099 | ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, | 1099 | ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, |
| 1100 | loff_t *, size_t, unsigned int); | 1100 | loff_t *, size_t, unsigned int); |
| 1101 | int ret; | ||
| 1102 | |||
| 1103 | if (unlikely(!(out->f_mode & FMODE_WRITE))) | ||
| 1104 | return -EBADF; | ||
| 1105 | |||
| 1106 | if (unlikely(out->f_flags & O_APPEND)) | ||
| 1107 | return -EINVAL; | ||
| 1108 | |||
| 1109 | ret = rw_verify_area(WRITE, out, ppos, len); | ||
| 1110 | if (unlikely(ret < 0)) | ||
| 1111 | return ret; | ||
| 1112 | 1101 | ||
| 1113 | if (out->f_op && out->f_op->splice_write) | 1102 | if (out->f_op && out->f_op->splice_write) |
| 1114 | splice_write = out->f_op->splice_write; | 1103 | splice_write = out->f_op->splice_write; |
| 1115 | else | 1104 | else |
| 1116 | splice_write = default_file_splice_write; | 1105 | splice_write = default_file_splice_write; |
| 1117 | 1106 | ||
| 1118 | file_start_write(out); | 1107 | return splice_write(pipe, out, ppos, len, flags); |
| 1119 | ret = splice_write(pipe, out, ppos, len, flags); | ||
| 1120 | file_end_write(out); | ||
| 1121 | return ret; | ||
| 1122 | } | 1108 | } |
| 1123 | 1109 | ||
| 1124 | /* | 1110 | /* |
| @@ -1307,6 +1293,16 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, | |||
| 1307 | }; | 1293 | }; |
| 1308 | long ret; | 1294 | long ret; |
| 1309 | 1295 | ||
| 1296 | if (unlikely(!(out->f_mode & FMODE_WRITE))) | ||
| 1297 | return -EBADF; | ||
| 1298 | |||
| 1299 | if (unlikely(out->f_flags & O_APPEND)) | ||
| 1300 | return -EINVAL; | ||
| 1301 | |||
| 1302 | ret = rw_verify_area(WRITE, out, opos, len); | ||
| 1303 | if (unlikely(ret < 0)) | ||
| 1304 | return ret; | ||
| 1305 | |||
| 1310 | ret = splice_direct_to_actor(in, &sd, direct_splice_actor); | 1306 | ret = splice_direct_to_actor(in, &sd, direct_splice_actor); |
| 1311 | if (ret > 0) | 1307 | if (ret > 0) |
| 1312 | *ppos = sd.pos; | 1308 | *ppos = sd.pos; |
| @@ -1362,7 +1358,19 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
| 1362 | offset = out->f_pos; | 1358 | offset = out->f_pos; |
| 1363 | } | 1359 | } |
| 1364 | 1360 | ||
| 1361 | if (unlikely(!(out->f_mode & FMODE_WRITE))) | ||
| 1362 | return -EBADF; | ||
| 1363 | |||
| 1364 | if (unlikely(out->f_flags & O_APPEND)) | ||
| 1365 | return -EINVAL; | ||
| 1366 | |||
| 1367 | ret = rw_verify_area(WRITE, out, &offset, len); | ||
| 1368 | if (unlikely(ret < 0)) | ||
| 1369 | return ret; | ||
| 1370 | |||
| 1371 | file_start_write(out); | ||
| 1365 | ret = do_splice_from(ipipe, out, &offset, len, flags); | 1372 | ret = do_splice_from(ipipe, out, &offset, len, flags); |
| 1373 | file_end_write(out); | ||
| 1366 | 1374 | ||
| 1367 | if (!off_out) | 1375 | if (!off_out) |
| 1368 | out->f_pos = offset; | 1376 | out->f_pos = offset; |
