• Miao Xie's avatar
    Btrfs: fix BUG_ON() caused by ENOSPC when relocating space · 199c36ea
    Miao Xie authored
    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: default avatarTsutomu Itoh <t-itoh@jp.fujitsu.com>
    Signed-off-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
    Tested-by: default avatarTsutomu Itoh <t-itoh@jp.fujitsu.com>
    Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
    199c36ea
extent-tree.c 193 KB