Arne Jansen
2011-May-05 14:16 UTC
[PATCH] btrfs progs: fix extra metadata chunk allocation in --mixed case
When creating a mixed fs with mkfs, an extra metadata chunk got allocated. This is because btrfs_reserve_extent calls do_chunk_alloc for METADATA, which in turn wasn''t able to find the proper space_info, as __find_space_info did a hard compare of the flags. It is now sufficient for the space_info to include the proper flag. This reflects the change done to the kernel code to support mixed chunks. Also for a subsequent chunk allocation (which should not be hit in the mkfs case), the chunk is now created with the flags from the space_info instead of the requested flags. A better solution would be to pull the full changeset for the mixed case from the kernel into the user mode (or, even better, share the code) The additional chunk probably confused block_rsv calculation, which in turn led to severeal ENOSPC Oopses. Signed-off-by: Arne Jansen <sensille@gmx.net> --- extent-tree.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/extent-tree.c b/extent-tree.c index b2f9bb2..c6c77c6 100644 --- a/extent-tree.c +++ b/extent-tree.c @@ -1735,7 +1735,7 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, struct btrfs_space_info *found; list_for_each(cur, head) { found = list_entry(cur, struct btrfs_space_info, list); - if (found->flags == flags) + if (found->flags & flags) return found; } return NULL; @@ -1812,7 +1812,8 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, thresh) return 0; - ret = btrfs_alloc_chunk(trans, extent_root, &start, &num_bytes, flags); + ret = btrfs_alloc_chunk(trans, extent_root, &start, &num_bytes, + space_info->flags); if (ret == -ENOSPC) { space_info->full = 1; return 0; @@ -1820,7 +1821,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, BUG_ON(ret); - ret = btrfs_make_block_group(trans, extent_root, 0, flags, + ret = btrfs_make_block_group(trans, extent_root, 0, space_info->flags, BTRFS_FIRST_CHUNK_TREE_OBJECTID, start, num_bytes); BUG_ON(ret); return 0; -- 1.7.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
liubo
2011-May-06 01:05 UTC
Re: [PATCH] btrfs progs: fix extra metadata chunk allocation in --mixed case
On 05/05/2011 10:16 PM, Arne Jansen wrote:> When creating a mixed fs with mkfs, an extra metadata chunk got allocated. > This is because btrfs_reserve_extent calls do_chunk_alloc for METADATA, > which in turn wasn''t able to find the proper space_info, as __find_space_info > did a hard compare of the flags. It is now sufficient for the space_info to > include the proper flag. This reflects the change done to the kernel code > to support mixed chunks. > Also for a subsequent chunk allocation (which should not be hit in the mkfs > case), the chunk is now created with the flags from the space_info instead > of the requested flags. A better solution would be to pull the full changeset > for the mixed case from the kernel into the user mode (or, even better, share > the code) > > The additional chunk probably confused block_rsv calculation, which in turn > led to severeal ENOSPC Oopses. >Good catch! Reviewed-by: Liu Bo <liubo2009@cn.fujitsu.com>> Signed-off-by: Arne Jansen <sensille@gmx.net> > --- > extent-tree.c | 7 ++++--- > 1 files changed, 4 insertions(+), 3 deletions(-) > > diff --git a/extent-tree.c b/extent-tree.c > index b2f9bb2..c6c77c6 100644 > --- a/extent-tree.c > +++ b/extent-tree.c > @@ -1735,7 +1735,7 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, > struct btrfs_space_info *found; > list_for_each(cur, head) { > found = list_entry(cur, struct btrfs_space_info, list); > - if (found->flags == flags) > + if (found->flags & flags) > return found; > } > return NULL; > @@ -1812,7 +1812,8 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, > thresh) > return 0; > > - ret = btrfs_alloc_chunk(trans, extent_root, &start, &num_bytes, flags); > + ret = btrfs_alloc_chunk(trans, extent_root, &start, &num_bytes, > + space_info->flags); > if (ret == -ENOSPC) { > space_info->full = 1; > return 0; > @@ -1820,7 +1821,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, > > BUG_ON(ret); > > - ret = btrfs_make_block_group(trans, extent_root, 0, flags, > + ret = btrfs_make_block_group(trans, extent_root, 0, space_info->flags, > BTRFS_FIRST_CHUNK_TREE_OBJECTID, start, num_bytes); > BUG_ON(ret); > return 0;-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Sergei Trofimovich
2011-May-06 20:39 UTC
Re: [PATCH] btrfs progs: fix extra metadata chunk allocation in --mixed case
> The additional chunk probably confused block_rsv calculation, which in turn > led to severeal ENOSPC Oopses.I confirm. This patch __FIXES__ ENOSPC OOpses like the following for me: (with applied http://www.spinics.net/lists/linux-btrfs/msg09400.html on top to avoid earlier OOpses) [14198.695903] BUG: unable to handle kernel NULL pointer dereference at 0000000000000030 [14198.695937] IP: [<ffffffffa021f597>] btrfs_print_leaf+0x27/0x890 [btrfs] [14198.695978] PGD 70b04067 PUD 6b9ef067 PMD 0 [14198.695991] Oops: 0000 [#1] PREEMPT SMP [14198.696003] last sysfs file: /sys/devices/virtual/vtconsole/vtcon1/uevent [14198.696015] CPU 0 [14198.696020] Modules linked in: bridge stp llc btrfs zlib_deflate lzo_decompress lzo_compress crc32c libcrc32c tun kvm_amd kvm fuse nouveau ttm drm_kms_helper drm forcedeth i2c_algo_bit i2c_core cfbcopyarea cfbimgblt cfbfillrect [14198.696088] [14198.696095] Pid: 1356, comm: btrfs-transacti Not tainted 2.6.39-rc5+ #10 To Be Filled By O.E.M. To Be Filled By O.E.M./ALiveNF6G-VSTA [14198.696116] RIP: 0010:[<ffffffffa021f597>] [<ffffffffa021f597>] btrfs_print_leaf+0x27/0x890 [btrfs] [14198.696139] RSP: 0018:ffff880076ecfad0 EFLAGS: 00010283 [14198.696147] RAX: 00000000ffffffe4 RBX: 0000000000000000 RCX: 00000000ffffffe4 [14198.696157] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000001 [14198.696167] RBP: ffff880076ecfb50 R08: 0000000000000000 R09: 0000000100000000 [14198.696178] R10: ffffffffffffffe4 R11: 0000000000000002 R12: 0000000000000002 [14198.696188] R13: ffff88007611b000 R14: 0000000000000000 R15: 0000000000000000 [14198.696200] FS: 00007f924fc1b700(0000) GS:ffff88007bc00000(0000) knlGS:0000000000000000 [14198.696212] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [14198.696221] CR2: 0000000000000030 CR3: 000000006b9b9000 CR4: 00000000000006f0 [14198.696231] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [14198.696242] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [14198.696253] Process btrfs-transacti (pid: 1356, threadinfo ffff880076ece000, task ffff8800760cac20) [14198.696265] Stack: [14198.696271] 000000010ce53000 ffffffff00000000 ffff88007611b000 0000000000000001 [14198.696287] ffff880076ecfbe0 ffff880077f37510 000000010ce53000 00000000001000a8 [14198.696305] ffff880076ecfb00 ffffffff810d29a7 ffff880076b9a840 ffff880077f37510 [14198.696322] Call Trace: [14198.696339] [<ffffffff810d29a7>] ? kmem_cache_alloc+0x97/0xb0 [14198.696352] [<ffffffffa0217907>] __btrfs_free_extent+0x647/0x700 [btrfs] [14198.696352] [<ffffffff8103b371>] ? get_parent_ip+0x11/0x50 [14198.696352] [<ffffffff8103b371>] ? get_parent_ip+0x11/0x50 [14198.696352] [<ffffffff8103b371>] ? get_parent_ip+0x11/0x50 [14198.696352] [<ffffffffa021a3f1>] run_clustered_refs+0x381/0x860 [btrfs] [14198.696352] [<ffffffffa026b200>] ? btrfs_find_ref_cluster+0x60/0x180 [btrfs] [14198.696352] [<ffffffffa021a990>] btrfs_run_delayed_refs+0xc0/0x210 [btrfs] [14198.696352] [<ffffffff81574700>] ? _raw_spin_unlock+0x10/0x40 [14198.696352] [<ffffffffa022b878>] btrfs_commit_transaction+0x78/0x780 [btrfs] [14198.696352] [<ffffffff8105c640>] ? wake_up_bit+0x40/0x40 [14198.696352] [<ffffffffa022518b>] transaction_kthread+0x27b/0x290 [btrfs] [14198.696352] [<ffffffff8103b445>] ? sub_preempt_count+0x95/0xd0 [14198.696352] [<ffffffffa0224f10>] ? btrfs_congested_fn+0x90/0x90 [btrfs] [14198.696352] [<ffffffff8105c166>] kthread+0x96/0xa0 [14198.696352] [<ffffffff81576014>] kernel_thread_helper+0x4/0x10 [14198.696352] [<ffffffff8105c0d0>] ? kthread_worker_fn+0x190/0x190 [14198.696352] [<ffffffff81576010>] ? gs_change+0xb/0xb [14198.696352] Code: 00 00 00 00 55 48 89 e5 48 83 c4 80 4c 89 6d e8 49 89 fd bf 01 00 00 00 48 89 5d d8 4c 89 65 e0 48 89 f3 4c 89 75 f0 4c 89 7d f8 <4c> 8b 66 30 e8 e0 be e1 e0 48 b8 00 00 00 00 00 16 00 00 49 01 [14198.696352] RIP [<ffffffffa021f597>] btrfs_print_leaf+0x27/0x890 [btrfs] [14198.696352] RSP <ffff880076ecfad0> [14198.696352] CR2: 0000000000000030 [14198.700320] ---[ end trace e55b8b088e0f1338 ]--- -- Sergei