splice: remove i_mutex locking in splice_from_pipe()
splice_from_pipe() is only called from two places: - generic_splice_sendpage() - splice_write_null() Neither of these require i_mutex to be taken on the destination inode. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
parent
b3c2d2ddd6
commit
2933970b96
fs
18
fs/splice.c
18
fs/splice.c
|
@ -784,7 +784,7 @@ EXPORT_SYMBOL(__splice_from_pipe);
|
||||||
* @actor: handler that splices the data
|
* @actor: handler that splices the data
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* See __splice_from_pipe. This function locks the input and output inodes,
|
* See __splice_from_pipe. This function locks the pipe inode,
|
||||||
* otherwise it's identical to __splice_from_pipe().
|
* otherwise it's identical to __splice_from_pipe().
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -793,7 +793,6 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
|
||||||
splice_actor *actor)
|
splice_actor *actor)
|
||||||
{
|
{
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
struct inode *inode = out->f_mapping->host;
|
|
||||||
struct splice_desc sd = {
|
struct splice_desc sd = {
|
||||||
.total_len = len,
|
.total_len = len,
|
||||||
.flags = flags,
|
.flags = flags,
|
||||||
|
@ -801,24 +800,11 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
|
||||||
.u.file = out,
|
.u.file = out,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* The actor worker might be calling ->write_begin and
|
|
||||||
* ->write_end. Most of the time, these expect i_mutex to
|
|
||||||
* be held. Since this may result in an ABBA deadlock with
|
|
||||||
* pipe->inode, we have to order lock acquiry here.
|
|
||||||
*
|
|
||||||
* Outer lock must be inode->i_mutex, as pipe_wait() will
|
|
||||||
* release and reacquire pipe->inode->i_mutex, AND inode must
|
|
||||||
* never be a pipe.
|
|
||||||
*/
|
|
||||||
WARN_ON(S_ISFIFO(inode->i_mode));
|
|
||||||
mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
|
|
||||||
if (pipe->inode)
|
if (pipe->inode)
|
||||||
mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD);
|
mutex_lock(&pipe->inode->i_mutex);
|
||||||
ret = __splice_from_pipe(pipe, &sd, actor);
|
ret = __splice_from_pipe(pipe, &sd, actor);
|
||||||
if (pipe->inode)
|
if (pipe->inode)
|
||||||
mutex_unlock(&pipe->inode->i_mutex);
|
mutex_unlock(&pipe->inode->i_mutex);
|
||||||
mutex_unlock(&inode->i_mutex);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue