Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2933970b authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Jens Axboe
Browse files

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: default avatarMiklos Szeredi <mszeredi@suse.cz>
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent b3c2d2dd
Loading
Loading
Loading
Loading
+2 −16
Original line number Diff line number Diff line
@@ -784,7 +784,7 @@ EXPORT_SYMBOL(__splice_from_pipe);
 * @actor:	handler that splices the data
 *
 * 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().
 *
 */
@@ -793,7 +793,6 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
			 splice_actor *actor)
{
	ssize_t ret;
	struct inode *inode = out->f_mapping->host;
	struct splice_desc sd = {
		.total_len = len,
		.flags = flags,
@@ -801,24 +800,11 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct 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)
		mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD);
		mutex_lock(&pipe->inode->i_mutex);
	ret = __splice_from_pipe(pipe, &sd, actor);
	if (pipe->inode)
		mutex_unlock(&pipe->inode->i_mutex);
	mutex_unlock(&inode->i_mutex);

	return ret;
}