From patchwork Thu Jan 14 17:03:23 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 72903 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o0EH3Zw4031423 for ; Thu, 14 Jan 2010 17:03:35 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757340Ab0ANRDd (ORCPT ); Thu, 14 Jan 2010 12:03:33 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1757337Ab0ANRDc (ORCPT ); Thu, 14 Jan 2010 12:03:32 -0500 Received: from mx1.redhat.com ([209.132.183.28]:49617 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757328Ab0ANRDc (ORCPT ); Thu, 14 Jan 2010 12:03:32 -0500 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o0EH3PkW011538 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 14 Jan 2010 12:03:25 -0500 Received: from localhost.localdomain (vpn-11-24.rdu.redhat.com [10.11.11.24]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o0EH3OnC010748; Thu, 14 Jan 2010 12:03:24 -0500 Date: Thu, 14 Jan 2010 12:03:23 -0500 From: Josef Bacik To: Tomas Carnecky Cc: Josef Bacik , linux-btrfs@vger.kernel.org Subject: Re: Bug in btrfs_rename (kernel BUG at fs/btrfs/inode.c:5595!) Message-ID: <20100114170323.GA2190@localhost.localdomain> References: <4B4E1A5D.1070203@gmail.com> <20100113201317.GC2774@dhcp231-156.rdu.redhat.com> <4B4E290F.9010100@gmail.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <4B4E290F.9010100@gmail.com> User-Agent: Mutt/1.5.19 (2009-01-05) X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5440bab..c255dcb 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2096,6 +2096,13 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode) */ ret = btrfs_insert_orphan_item(trans, root, inode->i_ino); + printk(KERN_ERR "Btrfs: orphan add %llu\n", (unsigned long long)inode->i_ino); + dump_stack(); + if (ret) { + printk(KERN_ERR "OH NO, ORPHAN ENTRY ALREADY EXISTS FOR %llu\n", + (unsigned long long)inode->i_ino); + } + return ret; } @@ -3293,10 +3300,10 @@ static int btrfs_setattr_size(struct inode *inode, struct iattr *attr) unsigned long nr; int ret; - if (attr->ia_size == inode->i_size) + if (attr->ia_size == i_size_read(inode)) return 0; - if (attr->ia_size > inode->i_size) { + if (attr->ia_size > i_size_read(inode)) { unsigned long limit; limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; if (attr->ia_size > inode->i_sb->s_maxbytes) @@ -3305,24 +3312,7 @@ static int btrfs_setattr_size(struct inode *inode, struct iattr *attr) send_sig(SIGXFSZ, current, 0); return -EFBIG; } - } - - ret = btrfs_reserve_metadata_space(root, 1); - if (ret) - return ret; - - trans = btrfs_start_transaction(root, 1); - btrfs_set_trans_block_group(trans, inode); - - ret = btrfs_orphan_add(trans, inode); - BUG_ON(ret); - - nr = trans->blocks_used; - btrfs_end_transaction(trans, root); - btrfs_unreserve_metadata_space(root, 1); - btrfs_btree_balance_dirty(root, nr); - if (attr->ia_size > inode->i_size) { ret = btrfs_cont_expand(inode, attr->ia_size); if (ret) { btrfs_truncate(inode); @@ -3345,6 +3335,21 @@ static int btrfs_setattr_size(struct inode *inode, struct iattr *attr) btrfs_end_transaction(trans, root); btrfs_btree_balance_dirty(root, nr); return 0; + } else if (attr->ia_size < i_size_read(inode)) { + ret = btrfs_reserve_metadata_space(root, 1); + if (ret) + return ret; + + trans = btrfs_start_transaction(root, 1); + btrfs_set_trans_block_group(trans, inode); + + ret = btrfs_orphan_add(trans, inode); + BUG_ON(ret); + + nr = trans->blocks_used; + btrfs_end_transaction(trans, root); + btrfs_unreserve_metadata_space(root, 1); + btrfs_btree_balance_dirty(root, nr); } /* @@ -3355,10 +3360,6 @@ static int btrfs_setattr_size(struct inode *inode, struct iattr *attr) if (attr->ia_size == 0) BTRFS_I(inode)->ordered_data_close = 1; - /* we don't support swapfiles, so vmtruncate shouldn't fail */ - ret = vmtruncate(inode, attr->ia_size); - BUG_ON(ret); - return 0; } @@ -3376,7 +3377,6 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) if (err) return err; } - attr->ia_valid &= ~ATTR_SIZE; if (attr->ia_valid) err = inode_setattr(inode, attr); @@ -5592,7 +5592,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, BUG_ON(ret); if (new_inode->i_nlink == 0) { ret = btrfs_orphan_add(trans, new_dentry->d_inode); - BUG_ON(ret); + BUG_ON(ret && ret != -EEXIST); } }