|
@@ -811,24 +811,19 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
|
|
|
{
|
|
|
struct address_space *mapping = out->f_mapping;
|
|
|
struct inode *inode = mapping->host;
|
|
|
- int killsuid, killpriv;
|
|
|
+ struct splice_desc sd = {
|
|
|
+ .total_len = len,
|
|
|
+ .flags = flags,
|
|
|
+ .pos = *ppos,
|
|
|
+ .u.file = out,
|
|
|
+ };
|
|
|
ssize_t ret;
|
|
|
- int err = 0;
|
|
|
-
|
|
|
- killpriv = security_inode_need_killpriv(out->f_path.dentry);
|
|
|
- killsuid = should_remove_suid(out->f_path.dentry);
|
|
|
- if (unlikely(killsuid || killpriv)) {
|
|
|
- mutex_lock(&inode->i_mutex);
|
|
|
- if (killpriv)
|
|
|
- err = security_inode_killpriv(out->f_path.dentry);
|
|
|
- if (!err && killsuid)
|
|
|
- err = __remove_suid(out->f_path.dentry, killsuid);
|
|
|
- mutex_unlock(&inode->i_mutex);
|
|
|
- if (err)
|
|
|
- return err;
|
|
|
- }
|
|
|
|
|
|
- ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
|
|
|
+ inode_double_lock(inode, pipe->inode);
|
|
|
+ ret = remove_suid(out->f_path.dentry);
|
|
|
+ if (likely(!ret))
|
|
|
+ ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
|
|
|
+ inode_double_unlock(inode, pipe->inode);
|
|
|
if (ret > 0) {
|
|
|
unsigned long nr_pages;
|
|
|
|
|
@@ -840,6 +835,8 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
|
|
|
* 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);
|