From patchwork Tue Dec 7 09:25:02 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Zhong X-Patchwork-Id: 382132 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oB79PErA004365 for ; Tue, 7 Dec 2010 09:25:14 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754984Ab0LGJZK (ORCPT ); Tue, 7 Dec 2010 04:25:10 -0500 Received: from mga02.intel.com ([134.134.136.20]:35566 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752940Ab0LGJZJ (ORCPT ); Tue, 7 Dec 2010 04:25:09 -0500 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 07 Dec 2010 01:25:09 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.59,310,1288594800"; d="scan'208";a="581289416" Received: from unknown (HELO localhost.localdomain) ([10.238.135.222]) by orsmga002.jf.intel.com with ESMTP; 07 Dec 2010 01:25:08 -0800 From: Xin Zhong To: linux-btrfs@vger.kernel.org Cc: xin.zhong@intel.com Subject: [PATCH] Btrfs: pwrite blocked when writing from the mmaped buffer of the same page Date: Tue, 7 Dec 2010 17:25:02 +0800 Message-Id: <1291713902-5149-1-git-send-email-xin.zhong@intel.com> X-Mailer: git-send-email 1.6.2.2 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Tue, 07 Dec 2010 09:25:14 +0000 (UTC) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index c1faded..805f2ee 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -57,11 +57,15 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, PAGE_CACHE_SIZE - offset, write_bytes); struct page *page = prepared_pages[pg]; again: - if (unlikely(iov_iter_fault_in_readable(i, count))) - return -EFAULT; - - /* Copy data from userspace to the current page */ - copied = iov_iter_copy_from_user(page, i, offset, count); + /* + * Copy data from userspace to the current page + * + * Disable pagefault to avoid recursive lock since + * the pages are already locked + */ + pagefault_disable(); + copied = iov_iter_copy_from_user_atomic(page, i, offset, count); + pagefault_enable(); /* Flush processor's dcache for this page */ flush_dcache_page(page); @@ -974,6 +978,15 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, if (ret) goto out; + /* + * fault pages before locking them in prepare_pages + * to avoid recursive lock + */ + if (unlikely(iov_iter_fault_in_readable(&i, write_bytes))) { + ret = -EFAULT; + goto out; + } + ret = prepare_pages(root, file, pages, num_pages, pos, first_index, last_index, write_bytes);