From mboxrd@z Thu Jan 1 00:00:00 1970 From: Josef Bacik Subject: Re: Bug in btrfs_rename (kernel BUG at fs/btrfs/inode.c:5595!) Date: Thu, 14 Jan 2010 14:00:04 -0500 Message-ID: <20100114190004.GB2190@localhost.localdomain> References: <4B4E1A5D.1070203@gmail.com> <20100113201317.GC2774@dhcp231-156.rdu.redhat.com> <4B4E290F.9010100@gmail.com> <20100114170323.GA2190@localhost.localdomain> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: Tomas Carnecky , linux-btrfs@vger.kernel.org To: Josef Bacik Return-path: In-Reply-To: <20100114170323.GA2190@localhost.localdomain> List-ID: On Thu, Jan 14, 2010 at 12:03:23PM -0500, Josef Bacik wrote: > On Wed, Jan 13, 2010 at 09:11:59PM +0100, Tomas Carnecky wrote: > > On 1/13/10 9:13 PM, Josef Bacik wrote: > >> On Wed, Jan 13, 2010 at 08:09:17PM +0100, Tomas Carnecky wrote: > >>> I was running v2.6.33-rc2-187-g08d869a and everything was ok. Today I > >>> decided to update the kernel (to v2.6.33-rc4) and a minute or two after > >>> logging into the gnome desktop this kernel bug appeared in dmesg. I then > >>> went back to the old kernel but the bug didn't disappear, not even after > >>> running btrfsck on the filesystem. > >>> > >> Ok will you please run with this patch? It shouldn't panic your box, since it > >> seems ret is -EEXIST. Just watch your logs for > >> > >> OH NO, ORPHAN ENTRY ALREADY EXISTS FOR > >> > >> and then look up and find all occurances of > >> > >> Btrfs: orphan add > >> > >> with the stack trace and send it back to me so I can verify that nothing heinous > >> is happening. I assume we're just racing with unlink/rename so all that needs > >> to be done is to take that BUG_ON out, but it would be nice to know for sure. > > > > Ok will you try this patch? I've not built it, so sorry if it doesn't compile > :). Look for the "OH NO" messages again. If they show up then the problem is > still there, if they go away the problem is fixed. I tried to reproduce this > locally but I can't seem to do it, so you are my only hope :). > > By the way, this replaces the last patch I sent you, so unapply the previous > patch and apply this one instead. Thanks, > Ok here's the final version of the patch I'm going to post. This replaces the other patches that I sent you, so un-apply the last one you applied and apply this one instead. Run this for a day and let me know if you have any problems. If no problems I'll go ahead and post it. Thanks, Josef diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5440bab..24cbf6b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3305,24 +3305,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); @@ -3337,14 +3320,26 @@ static int btrfs_setattr_size(struct inode *inode, struct iattr *attr) ret = btrfs_update_inode(trans, root, inode); BUG_ON(ret); - if (inode->i_nlink > 0) { - ret = btrfs_orphan_del(trans, inode); - BUG_ON(ret); - } + nr = trans->blocks_used; 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 +3350,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 +3367,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);