• M
    Btrfs: fix BUG_ON() caused by ENOSPC when relocating space · 199c36ea
    Miao Xie 提交于
    When we balanced the chunks across the devices, BUG_ON() in
    __finish_chunk_alloc() was triggered.
    
    ------------[ cut here ]------------
    kernel BUG at fs/btrfs/volumes.c:2568!
    [SNIP]
    Call Trace:
     [<ffffffffa049525e>] btrfs_alloc_chunk+0x8e/0xa0 [btrfs]
     [<ffffffffa04546b0>] do_chunk_alloc+0x330/0x3a0 [btrfs]
     [<ffffffffa045c654>] btrfs_reserve_extent+0xb4/0x1f0 [btrfs]
     [<ffffffffa045c86b>] btrfs_alloc_free_block+0xdb/0x350 [btrfs]
     [<ffffffffa048a8d8>] ? read_extent_buffer+0xd8/0x1d0 [btrfs]
     [<ffffffffa04476fd>] __btrfs_cow_block+0x14d/0x5e0 [btrfs]
     [<ffffffffa044660d>] ? read_block_for_search+0x14d/0x4d0 [btrfs]
     [<ffffffffa0447c9b>] btrfs_cow_block+0x10b/0x240 [btrfs]
     [<ffffffffa044dd5e>] btrfs_search_slot+0x49e/0x7a0 [btrfs]
     [<ffffffffa044f07d>] btrfs_insert_empty_items+0x8d/0xf0 [btrfs]
     [<ffffffffa045e973>] insert_with_overflow+0x43/0x110 [btrfs]
     [<ffffffffa045eb0d>] btrfs_insert_dir_item+0xcd/0x1f0 [btrfs]
     [<ffffffffa0489bd0>] ? map_extent_buffer+0xb0/0xc0 [btrfs]
     [<ffffffff812276ad>] ? rb_insert_color+0x9d/0x160
     [<ffffffffa046cc40>] ? inode_tree_add+0xf0/0x150 [btrfs]
     [<ffffffffa0474801>] btrfs_add_link+0xc1/0x1c0 [btrfs]
     [<ffffffff811dacac>] ? security_inode_init_security+0x1c/0x30
     [<ffffffffa04a28aa>] ? btrfs_init_acl+0x4a/0x180 [btrfs]
     [<ffffffffa047492f>] btrfs_add_nondir+0x2f/0x70 [btrfs]
     [<ffffffffa046af16>] ? btrfs_init_inode_security+0x46/0x60 [btrfs]
     [<ffffffffa0474ac0>] btrfs_create+0x150/0x1d0 [btrfs]
     [<ffffffff81159c63>] ? generic_permission+0x23/0xb0
     [<ffffffff8115b415>] vfs_create+0xa5/0xc0
     [<ffffffff8115ce6e>] do_last+0x5fe/0x880
     [<ffffffff8115dc0d>] path_openat+0xcd/0x3d0
     [<ffffffff8115e029>] do_filp_open+0x49/0xa0
     [<ffffffff8116a965>] ? alloc_fd+0x95/0x160
     [<ffffffff8114f0c7>] do_sys_open+0x107/0x1e0
     [<ffffffff810bcc3f>] ? audit_syscall_entry+0x1bf/0x1f0
     [<ffffffff8114f1e0>] sys_open+0x20/0x30
     [<ffffffff81484ec2>] system_call_fastpath+0x16/0x1b
    [SNIP]
    RIP  [<ffffffffa049444a>] __finish_chunk_alloc+0x20a/0x220 [btrfs]
    
    The reason is:
    Task1					Space balance task
    do_chunk_alloc()
      __finish_chunk_alloc()
        update device info
        in the chunk tree
          alloc system metadata block
    					relocate system metadata block group
    					  set system metadata block group
    					  readonly, This block group is the
    					  only one that can allocate space. So
    					  there is no free space that can be
    					  allocated now.
            find no space and don't try
            to alloc new chunk, and then
            return ENOSPC
      BUG_ON() in __finish_chunk_alloc()
      was triggered.
    
    Fix this bug by allocating a new system metadata chunk before relocating the
    old one if we find there is no free space which can be allocated after setting
    the old block group to be read-only.
    Reported-by: NTsutomu Itoh <t-itoh@jp.fujitsu.com>
    Signed-off-by: NMiao Xie <miaox@cn.fujitsu.com>
    Tested-by: NTsutomu Itoh <t-itoh@jp.fujitsu.com>
    Signed-off-by: NChris Mason <chris.mason@oracle.com>
    199c36ea
extent-tree.c 192.6 KB