From patchwork Thu Feb 19 14:24:48 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 23432 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id B97B4DDD1B for ; Fri, 20 Feb 2009 01:24:56 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751494AbZBSOYx (ORCPT ); Thu, 19 Feb 2009 09:24:53 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753342AbZBSOYx (ORCPT ); Thu, 19 Feb 2009 09:24:53 -0500 Received: from cantor.suse.de ([195.135.220.2]:52349 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751494AbZBSOYw (ORCPT ); Thu, 19 Feb 2009 09:24:52 -0500 Received: from Relay2.suse.de (relay-ext.suse.de [195.135.221.8]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id 54F30456F7; Thu, 19 Feb 2009 15:24:50 +0100 (CET) Received: from duck.suse.cz (duck.suse.cz [10.20.1.74]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.suse.cz (Postfix) with ESMTP id 94EC262807F; Thu, 19 Feb 2009 15:24:49 +0100 (CET) Received: by duck.suse.cz (Postfix, from userid 10005) id 2E2081F1E2A; Thu, 19 Feb 2009 15:24:49 +0100 (CET) From: Jan Kara To: linux-ext4@vger.kernel.org Cc: tytso@mit.edu, Jan Kara Subject: [PATCH] ext4: Fix deadlock in ext4_write_begin() and ext4_da_write_begin() Date: Thu, 19 Feb 2009 15:24:48 +0100 Message-Id: <1235053488-16937-1-git-send-email-jack@suse.cz> X-Mailer: git-send-email 1.6.0.2 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Functions ext4_write_begin() and ext4_da_write_begin() call grab_cache_page_write_begin() without AOP_FLAG_NOFS. Thus it can happen that page reclaim is triggered in that function and it recurses back into the filesystem (or some other filesystem). But this can lead to various problems as a transaction is already started at that point. Add the necessary flag. (Reported in http://bugzilla.kernel.org/show_bug.cgi?id=11688) Signed-off-by: Jan Kara Signed-off-by: "Theodore Ts'o" --- fs/ext4/inode.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 03ba20b..e62e6e4 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1366,6 +1366,10 @@ retry: goto out; } + /* We cannot recurse into the filesystem as the transaction is already + * started */ + flags |= AOP_FLAG_NOFS; + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { ext4_journal_stop(handle); @@ -1375,7 +1379,7 @@ retry: *pagep = page; ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, - ext4_get_block); + ext4_get_block); if (!ret && ext4_should_journal_data(inode)) { ret = walk_page_buffers(handle, page_buffers(page), @@ -2648,6 +2652,9 @@ retry: ret = PTR_ERR(handle); goto out; } + /* We cannot recurse into the filesystem as the transaction is already + * started */ + flags |= AOP_FLAG_NOFS; page = grab_cache_page_write_begin(mapping, index, flags); if (!page) {