From patchwork Sat Jun 6 00:22:21 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 28174 Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id DC343B70AE for ; Sat, 6 Jun 2009 10:22:28 +1000 (EST) Received: by ozlabs.org (Postfix) id CB492DDDA0; Sat, 6 Jun 2009 10:22:28 +1000 (EST) 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 61DCFDDD1B for ; Sat, 6 Jun 2009 10:22:28 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752701AbZFFAWY (ORCPT ); Fri, 5 Jun 2009 20:22:24 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752776AbZFFAWY (ORCPT ); Fri, 5 Jun 2009 20:22:24 -0400 Received: from cantor.suse.de ([195.135.220.2]:50615 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752701AbZFFAWX (ORCPT ); Fri, 5 Jun 2009 20:22:23 -0400 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 022F074609; Sat, 6 Jun 2009 02:22:22 +0200 (CEST) Received: by duck.suse.cz (Postfix, from userid 10005) id A3B7C252BFE; Sat, 6 Jun 2009 02:22:21 +0200 (CEST) From: Jan Kara To: Andrew Morton Cc: linux-ext4@vger.kernel.org, Jan Kara , Theodore Ts'o Subject: [PATCH] ext3: Make sure inode is deleted from orphan list after truncate Date: Sat, 6 Jun 2009 02:22:21 +0200 Message-Id: <1244247741-32037-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 As Ted pointed out, it can happen that ext3_truncate() returns without removing inode from orphan list. This way we could in some rare cases (like when we get ENOMEM from an allocation in ext3_truncate called because of failed ext3_write_begin) leave the inode on orphan list and that triggers assertion failure on umount. So make ext3_truncate() always remove inode from in-memory orphan list. CC: Theodore Ts'o Signed-off-by: Jan Kara --- fs/ext3/inode.c | 20 +++++++++++--------- 1 files changed, 11 insertions(+), 9 deletions(-) Andrew, would you please merge the patch? Thanks. diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index fcfa243..b50d35d 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -2374,7 +2374,7 @@ void ext3_truncate(struct inode *inode) struct page *page; if (!ext3_can_truncate(inode)) - return; + goto out_notrans; if (inode->i_size == 0 && ext3_should_writeback_data(inode)) ei->i_state |= EXT3_STATE_FLUSH_ON_CLOSE; @@ -2390,7 +2390,7 @@ void ext3_truncate(struct inode *inode) page = grab_cache_page(mapping, inode->i_size >> PAGE_CACHE_SHIFT); if (!page) - return; + goto out_notrans; } handle = start_transaction(inode); @@ -2401,7 +2401,7 @@ void ext3_truncate(struct inode *inode) unlock_page(page); page_cache_release(page); } - return; /* AKPM: return what? */ + goto out_notrans; } last_block = (inode->i_size + blocksize-1) @@ -2525,6 +2525,14 @@ out_stop: ext3_orphan_del(handle, inode); ext3_journal_stop(handle); + return; +out_notrans: + /* + * Delete the inode from orphan list so that it doesn't stay there + * forever and trigger assertion on umount. + */ + if (inode->i_nlink) + ext3_orphan_del(NULL, inode); } static ext3_fsblk_t ext3_get_inode_block(struct super_block *sb, @@ -3123,12 +3131,6 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) rc = inode_setattr(inode, attr); - /* If inode_setattr's call to ext3_truncate failed to get a - * transaction handle at all, we need to clean up the in-core - * orphan list manually. */ - if (inode->i_nlink) - ext3_orphan_del(NULL, inode); - if (!rc && (ia_valid & ATTR_MODE)) rc = ext3_acl_chmod(inode);