mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-04 02:06:43 +07:00
[PATCH] splice: offset fixes
- We need to adjust *ppos for writes as well. - Copy back modified offset value if one was passed in, similar to what sendfile does. Signed-off-by: Jens Axboe <axboe@suse.de>
This commit is contained in:
parent
2a27250e6c
commit
a4514ebd8e
45
fs/splice.c
45
fs/splice.c
@ -720,22 +720,26 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
|
|||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
ret = move_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
|
ret = move_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
|
||||||
|
if (ret > 0) {
|
||||||
/*
|
|
||||||
* If file or inode is SYNC and we actually wrote some data, sync it.
|
|
||||||
*/
|
|
||||||
if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(mapping->host))
|
|
||||||
&& ret > 0) {
|
|
||||||
struct inode *inode = mapping->host;
|
struct inode *inode = mapping->host;
|
||||||
int err;
|
|
||||||
|
|
||||||
mutex_lock(&inode->i_mutex);
|
*ppos += ret;
|
||||||
err = generic_osync_inode(mapping->host, mapping,
|
|
||||||
OSYNC_METADATA|OSYNC_DATA);
|
|
||||||
mutex_unlock(&inode->i_mutex);
|
|
||||||
|
|
||||||
if (err)
|
/*
|
||||||
ret = err;
|
* If file or inode is SYNC and we actually wrote some data,
|
||||||
|
* sync it.
|
||||||
|
*/
|
||||||
|
if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
mutex_lock(&inode->i_mutex);
|
||||||
|
err = generic_osync_inode(inode, mapping,
|
||||||
|
OSYNC_METADATA|OSYNC_DATA);
|
||||||
|
mutex_unlock(&inode->i_mutex);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
ret = err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -937,6 +941,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
|
|||||||
{
|
{
|
||||||
struct pipe_inode_info *pipe;
|
struct pipe_inode_info *pipe;
|
||||||
loff_t offset, *off;
|
loff_t offset, *off;
|
||||||
|
long ret;
|
||||||
|
|
||||||
pipe = in->f_dentry->d_inode->i_pipe;
|
pipe = in->f_dentry->d_inode->i_pipe;
|
||||||
if (pipe) {
|
if (pipe) {
|
||||||
@ -951,7 +956,12 @@ static long do_splice(struct file *in, loff_t __user *off_in,
|
|||||||
} else
|
} else
|
||||||
off = &out->f_pos;
|
off = &out->f_pos;
|
||||||
|
|
||||||
return do_splice_from(pipe, out, off, len, flags);
|
ret = do_splice_from(pipe, out, off, len, flags);
|
||||||
|
|
||||||
|
if (off_out && copy_to_user(off_out, off, sizeof(loff_t)))
|
||||||
|
ret = -EFAULT;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe = out->f_dentry->d_inode->i_pipe;
|
pipe = out->f_dentry->d_inode->i_pipe;
|
||||||
@ -967,7 +977,12 @@ static long do_splice(struct file *in, loff_t __user *off_in,
|
|||||||
} else
|
} else
|
||||||
off = &in->f_pos;
|
off = &in->f_pos;
|
||||||
|
|
||||||
return do_splice_to(in, off, pipe, len, flags);
|
ret = do_splice_to(in, off, pipe, len, flags);
|
||||||
|
|
||||||
|
if (off_in && copy_to_user(off_in, off, sizeof(loff_t)))
|
||||||
|
ret = -EFAULT;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
Loading…
Reference in New Issue
Block a user