From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1762354AbZENW7Z (ORCPT ); Thu, 14 May 2009 18:59:25 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1757258AbZENWnB (ORCPT ); Thu, 14 May 2009 18:43:01 -0400 Received: from kroah.org ([198.145.64.141]:52735 "EHLO coco.kroah.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756355AbZENWmj (ORCPT ); Thu, 14 May 2009 18:42:39 -0400 X-Mailbox-Line: From gregkh@mini.kroah.org Thu May 14 15:35:28 2009 Message-Id: <20090514223528.265736331@mini.kroah.org> User-Agent: quilt/0.48-1 Date: Thu, 14 May 2009 15:33:23 -0700 From: Greg KH To: linux-kernel@vger.kernel.org, stable@kernel.org Cc: Justin Forbes , Zwane Mwaikambo , "Theodore Ts'o" , Randy Dunlap , Dave Jones , Chuck Wolber , Chris Wedgwood , Michael Krufky , Chuck Ebbert , Domenico Andreoli , Willy Tarreau , Rodrigo Rubira Branco , Jake Edge , Eugene Teo , torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, Miklos Szeredi , Jens Axboe Subject: [patch 48/51] splice: fix i_mutex locking in generic_splice_write() References: <20090514223235.348540705@mini.kroah.org> Content-Disposition: inline; filename=splice-fix-i_mutex-locking-in-generic_splice_write.patch In-Reply-To: <20090514223755.GA27019@kroah.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 2.6.29-stable review patch. If anyone has any objections, please let us know. ------------------ From: Miklos Szeredi commit eb443e5a25d43996deb62b9bcee1a4ce5dea2ead upstream. Rearrange locking of i_mutex on destination so it's only held while buffers are copied with the pipe_to_file() actor, and not while waiting for more data on the pipe. Signed-off-by: Miklos Szeredi Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- fs/splice.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) --- a/fs/splice.c +++ b/fs/splice.c @@ -894,17 +894,29 @@ generic_file_splice_write(struct pipe_in }; ssize_t ret; - WARN_ON(S_ISFIFO(inode->i_mode)); - mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); - ret = file_remove_suid(out); - if (likely(!ret)) { - if (pipe->inode) - mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD); - ret = __splice_from_pipe(pipe, &sd, pipe_to_file); - if (pipe->inode) - mutex_unlock(&pipe->inode->i_mutex); - } - mutex_unlock(&inode->i_mutex); + if (pipe->inode) + mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_PARENT); + + splice_from_pipe_begin(&sd); + do { + ret = splice_from_pipe_next(pipe, &sd); + if (ret <= 0) + break; + + mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); + ret = file_remove_suid(out); + if (!ret) + ret = splice_from_pipe_feed(pipe, &sd, pipe_to_file); + mutex_unlock(&inode->i_mutex); + } while (ret > 0); + splice_from_pipe_end(pipe, &sd); + + if (pipe->inode) + mutex_unlock(&pipe->inode->i_mutex); + + if (sd.num_spliced) + ret = sd.num_spliced; + if (ret > 0) { unsigned long nr_pages;