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; |