splice: don't pass the address of ->f_pos to methods

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro
2013-06-20 18:58:36 +04:00
parent c9036e9f3b
commit 7995bd2871
5 changed files with 41 additions and 23 deletions

View File

@@ -1274,7 +1274,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
{
struct file *file = sd->u.file;
return do_splice_from(pipe, file, &file->f_pos, sd->total_len,
return do_splice_from(pipe, file, sd->opos, sd->total_len,
sd->flags);
}
@@ -1294,7 +1294,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
*
*/
long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
size_t len, unsigned int flags)
loff_t *opos, size_t len, unsigned int flags)
{
struct splice_desc sd = {
.len = len,
@@ -1302,6 +1302,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
.flags = flags,
.pos = *ppos,
.u.file = out,
.opos = opos,
};
long ret;
@@ -1325,7 +1326,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
{
struct pipe_inode_info *ipipe;
struct pipe_inode_info *opipe;
loff_t offset, *off;
loff_t offset;
long ret;
ipipe = get_pipe_info(in);
@@ -1356,13 +1357,15 @@ static long do_splice(struct file *in, loff_t __user *off_in,
return -EINVAL;
if (copy_from_user(&offset, off_out, sizeof(loff_t)))
return -EFAULT;
off = &offset;
} else
off = &out->f_pos;
} else {
offset = out->f_pos;
}
ret = do_splice_from(ipipe, out, off, len, flags);
ret = do_splice_from(ipipe, out, &offset, len, flags);
if (off_out && copy_to_user(off_out, off, sizeof(loff_t)))
if (!off_out)
out->f_pos = offset;
else if (copy_to_user(off_out, &offset, sizeof(loff_t)))
ret = -EFAULT;
return ret;
@@ -1376,13 +1379,15 @@ static long do_splice(struct file *in, loff_t __user *off_in,
return -EINVAL;
if (copy_from_user(&offset, off_in, sizeof(loff_t)))
return -EFAULT;
off = &offset;
} else
off = &in->f_pos;
} else {
offset = in->f_pos;
}
ret = do_splice_to(in, off, opipe, len, flags);
ret = do_splice_to(in, &offset, opipe, len, flags);
if (off_in && copy_to_user(off_in, off, sizeof(loff_t)))
if (!off_in)
in->f_pos = offset;
else if (copy_to_user(off_in, &offset, sizeof(loff_t)))
ret = -EFAULT;
return ret;