aboutsummaryrefslogtreecommitdiffstats
path: root/fs/splice.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/splice.c')
-rw-r--r--fs/splice.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/fs/splice.c b/fs/splice.c
index 7394e9e17534..9313b6124a2e 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -30,6 +30,7 @@
30#include <linux/syscalls.h> 30#include <linux/syscalls.h>
31#include <linux/uio.h> 31#include <linux/uio.h>
32#include <linux/security.h> 32#include <linux/security.h>
33#include <linux/gfp.h>
33 34
34/* 35/*
35 * Attempt to steal a page from a pipe buffer. This should perhaps go into 36 * Attempt to steal a page from a pipe buffer. This should perhaps go into
@@ -648,9 +649,11 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
648 ret = buf->ops->confirm(pipe, buf); 649 ret = buf->ops->confirm(pipe, buf);
649 if (!ret) { 650 if (!ret) {
650 more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; 651 more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
651 652 if (file->f_op && file->f_op->sendpage)
652 ret = file->f_op->sendpage(file, buf->page, buf->offset, 653 ret = file->f_op->sendpage(file, buf->page, buf->offset,
653 sd->len, &pos, more); 654 sd->len, &pos, more);
655 else
656 ret = -EINVAL;
654 } 657 }
655 658
656 return ret; 659 return ret;
@@ -1068,8 +1071,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
1068 if (unlikely(ret < 0)) 1071 if (unlikely(ret < 0))
1069 return ret; 1072 return ret;
1070 1073
1071 splice_write = out->f_op->splice_write; 1074 if (out->f_op && out->f_op->splice_write)
1072 if (!splice_write) 1075 splice_write = out->f_op->splice_write;
1076 else
1073 splice_write = default_file_splice_write; 1077 splice_write = default_file_splice_write;
1074 1078
1075 return splice_write(pipe, out, ppos, len, flags); 1079 return splice_write(pipe, out, ppos, len, flags);
@@ -1093,8 +1097,9 @@ static long do_splice_to(struct file *in, loff_t *ppos,
1093 if (unlikely(ret < 0)) 1097 if (unlikely(ret < 0))
1094 return ret; 1098 return ret;
1095 1099
1096 splice_read = in->f_op->splice_read; 1100 if (in->f_op && in->f_op->splice_read)
1097 if (!splice_read) 1101 splice_read = in->f_op->splice_read;
1102 else
1098 splice_read = default_file_splice_read; 1103 splice_read = default_file_splice_read;
1099 1104
1100 return splice_read(in, ppos, pipe, len, flags); 1105 return splice_read(in, ppos, pipe, len, flags);
@@ -1316,7 +1321,8 @@ static long do_splice(struct file *in, loff_t __user *off_in,
1316 if (off_in) 1321 if (off_in)
1317 return -ESPIPE; 1322 return -ESPIPE;
1318 if (off_out) { 1323 if (off_out) {
1319 if (out->f_op->llseek == no_llseek) 1324 if (!out->f_op || !out->f_op->llseek ||
1325 out->f_op->llseek == no_llseek)
1320 return -EINVAL; 1326 return -EINVAL;
1321 if (copy_from_user(&offset, off_out, sizeof(loff_t))) 1327 if (copy_from_user(&offset, off_out, sizeof(loff_t)))
1322 return -EFAULT; 1328 return -EFAULT;
@@ -1336,7 +1342,8 @@ static long do_splice(struct file *in, loff_t __user *off_in,
1336 if (off_out) 1342 if (off_out)
1337 return -ESPIPE; 1343 return -ESPIPE;
1338 if (off_in) { 1344 if (off_in) {
1339 if (in->f_op->llseek == no_llseek) 1345 if (!in->f_op || !in->f_op->llseek ||
1346 in->f_op->llseek == no_llseek)
1340 return -EINVAL; 1347 return -EINVAL;
1341 if (copy_from_user(&offset, off_in, sizeof(loff_t))) 1348 if (copy_from_user(&offset, off_in, sizeof(loff_t)))
1342 return -EFAULT; 1349 return -EFAULT;