]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
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)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 18 May 2009 23:35:22 +0000 (16:35 -0700)
commit 2933970b960223076d6affcf7a77e2bc546b8102 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/splice.c

index 89a802678a146dd16baa36365d1ad695873b55b0..f88614d4a928c035f2c2ff743ad21038f0ebe67b 100644 (file)
@@ -783,7 +783,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().
  *
  */
@@ -792,7 +792,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,
@@ -800,24 +799,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;
 }