splice: remove i_mutex locking in splice_from_pipe()
authorMiklos Szeredi <miklos@szeredi.hu>
Tue, 14 Apr 2009 17:48:37 +0000 (19:48 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Wed, 15 Apr 2009 10:10:11 +0000 (12:10 +0200)
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>
fs/splice.c

index fd6b278d447b3b7e36a629d2e2ecc4578bc6f6b8..349576b2c75a8076279696d86cf464f7de55f067 100644 (file)
@@ -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;
 }