2011/10/13 Josef Bacik <jo...@redhat.com>: [...] >> >> [ 175.956273] kernel BUG at fs/btrfs/inode.c:2176! >> > >> > Ok I think I see what's happening, this patch replaces the previous one, >> > let me >> > know how it goes. Thanks, >> > >> >> Getting a slightly different BUG this time: >> > > Ok looks like I've fixed the original problem and now we're hitting a problem > with the free space cache. This patch will replace the last one, its all the > fixes up to now and a new set of BUG_ON()'s to figure out which free space > cache > inode is screwing us up. Thanks, > > Josef > > > diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c > index fc0de68..e595372 100644 > --- a/fs/btrfs/extent-tree.c > +++ b/fs/btrfs/extent-tree.c > @@ -3334,7 +3334,7 @@ out: > * shrink metadata reservation for delalloc > */ > static int shrink_delalloc(struct btrfs_trans_handle *trans, > - struct btrfs_root *root, u64 to_reclaim, int sync) > + struct btrfs_root *root, u64 to_reclaim, int > retries) > { > struct btrfs_block_rsv *block_rsv; > struct btrfs_space_info *space_info; > @@ -3365,12 +3365,10 @@ static int shrink_delalloc(struct btrfs_trans_handle > *trans, > } > > max_reclaim = min(reserved, to_reclaim); > + if (max_reclaim > (2 * 1024 * 1024)) > + nr_pages = max_reclaim >> PAGE_CACHE_SHIFT; > > while (loops < 1024) { > - /* have the flusher threads jump in and do some IO */ > - smp_mb(); > - nr_pages = min_t(unsigned long, nr_pages, > - root->fs_info->delalloc_bytes >> PAGE_CACHE_SHIFT); > writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages); > > spin_lock(&space_info->lock); > @@ -3384,14 +3382,22 @@ static int shrink_delalloc(struct btrfs_trans_handle > *trans, > if (reserved == 0 || reclaimed >= max_reclaim) > break; > > - if (trans && trans->transaction->blocked) > + if (trans) > return -EAGAIN; > > - time_left = schedule_timeout_interruptible(1); > + if (!retries) { > + time_left = schedule_timeout_interruptible(1); > > - /* We were interrupted, exit */ > - if (time_left) > - break; > + /* We were interrupted, exit */ > + if (time_left) > + break; > + } else { > + /* > + * We've already done this song and dance once, let's > + * really wait for some work to get done. > + */ > + btrfs_wait_ordered_extents(root, 0, 0); > + } > > /* we've kicked the IO a few times, if anything has been freed, > * exit. There is no sense in looping here for a long time > @@ -3399,15 +3405,13 @@ static int shrink_delalloc(struct btrfs_trans_handle > *trans, > * just too many writers without enough free space > */ > > - if (loops > 3) { > + if (!retries && loops > 3) { > smp_mb(); > if (progress != space_info->reservation_progress) > break; > } > > } > - if (reclaimed < to_reclaim && !trans) > - btrfs_wait_ordered_extents(root, 0, 0); > return reclaimed >= to_reclaim; > } > > @@ -3552,7 +3556,7 @@ again: > * We do synchronous shrinking since we don't actually unreserve > * metadata until after the IO is completed. > */ > - ret = shrink_delalloc(trans, root, num_bytes, 1); > + ret = shrink_delalloc(trans, root, num_bytes, retries); > if (ret < 0) > goto out; > > @@ -3568,17 +3572,6 @@ again: > goto again; > } > > - /* > - * Not enough space to be reclaimed, don't bother committing the > - * transaction. > - */ > - spin_lock(&space_info->lock); > - if (space_info->bytes_pinned < orig_bytes) > - ret = -ENOSPC; > - spin_unlock(&space_info->lock); > - if (ret) > - goto out; > - > ret = -EAGAIN; > if (trans) > goto out; > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c > index d6ba353..cb63904 100644 > --- a/fs/btrfs/inode.c > +++ b/fs/btrfs/inode.c > @@ -782,7 +782,8 @@ static noinline int cow_file_range(struct inode *inode, > struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; > int ret = 0; > > - BUG_ON(btrfs_is_free_space_inode(root, inode)); > + BUG_ON(root == root->fs_info->tree_root); > + BUG_ON(BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID); > trans = btrfs_join_transaction(root); > BUG_ON(IS_ERR(trans)); > trans->block_rsv = &root->fs_info->delalloc_block_rsv; > @@ -2790,7 +2791,8 @@ static struct btrfs_trans_handle > *__unlink_start_trans(struct inode *dir, > return ERR_PTR(-ENOMEM); > } > > - trans = btrfs_start_transaction(root, 0); > + /* 1 for the orphan item */ > + trans = btrfs_start_transaction(root, 1); > if (IS_ERR(trans)) { > btrfs_free_path(path); > root->fs_info->enospc_unlink = 0;
Could it be, that the missing space for the orphan item, is the reason for our warning? [ 105.209232] ------------[ cut here ]------------ [ 105.214458] WARNING: at fs/btrfs/inode.c:2114 btrfs_orphan_commit_root+0xb0/0xc0 [btrfs]() [ 105.223794] Hardware name: ProLiant DL180 G6 [ 105.228930] Modules linked in: btrfs zlib_deflate libcrc32c bonding ipv6 serio_raw pcspkr ghes hed iTCO_wdt iTCO_vendor_support i7core_edac edac_core ixgbe dca mdio iomemory_vsl(P) hpsa squashfs [last unloaded: scsi_wait_scan] [ 105.253539] Pid: 1774, comm: kworker/0:2 Tainted: P 3.0.6-1.fits.2.el6.x86_64 #1 [ 105.263015] Call Trace: [ 105.265956] [<ffffffff8106344f>] warn_slowpath_common+0x7f/0xc0 [ 105.272841] [<ffffffff810634aa>] warn_slowpath_null+0x1a/0x20 [ 105.279503] [<ffffffffa022bef0>] btrfs_orphan_commit_root+0xb0/0xc0 [btrfs] [ 105.287564] [<ffffffffa0226ce5>] commit_fs_roots+0xc5/0x1b0 [btrfs] [ 105.294824] [<ffffffffa0227c36>] btrfs_commit_transaction+0x3c6/0x820 [btrfs] [ 105.303044] [<ffffffff810507c0>] ? __dequeue_entity+0x30/0x50 [ 105.309745] [<ffffffff81086410>] ? wake_up_bit+0x40/0x40 [ 105.315944] [<ffffffffa0228090>] ? btrfs_commit_transaction+0x820/0x820 [btrfs] [ 105.324404] [<ffffffffa02280af>] do_async_commit+0x1f/0x30 [btrfs] [ 105.331590] [<ffffffff8107e8b8>] process_one_work+0x128/0x450 [ 105.338291] [<ffffffff810816cb>] worker_thread+0x17b/0x3c0 [ 105.344708] [<ffffffff81081550>] ? manage_workers+0x220/0x220 [ 105.351407] [<ffffffff81085d96>] kthread+0x96/0xa0 [ 105.357040] [<ffffffff815639c4>] kernel_thread_helper+0x4/0x10 [ 105.363824] [<ffffffff81085d00>] ? kthread_worker_fn+0x1a0/0x1a0 [ 105.370776] [<ffffffff815639c0>] ? gs_change+0x13/0x13 [ 105.376771] ---[ end trace 144230b62b45be67 ]--- Thanks, Christian > @@ -2901,6 +2903,11 @@ out: > return ERR_PTR(err); > } > > + ret = btrfs_block_rsv_migrate(trans->block_rsv, > + &root->fs_info->global_block_rsv, > + btrfs_calc_trans_metadata_size(root, > 1)); > + BUG_ON(ret); > + > trans->block_rsv = &root->fs_info->global_block_rsv; > return trans; > } > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html