• Miao Xie's avatar
    Btrfs: fix race between multi-task space allocation and caching space · 60d2adbb
    Miao Xie authored
    The task may fail to get free space though it is enough when multi-task
    space allocation and caching space happen at the same time.
    
    	Task1			Caching Thread		Task2
    	------------------------------------------------------------------------
    	find_free_extent
    	  The space has not
    	  be cached, and start
    	  caching thread. And
    	  wait for it.
    				cache space, if
    				the space is > 2MB
    				wake up Task1
    							find_free_extent
    							  get all the space that
    							  is cached.
    	  try to allocate space,
    	  but there is no space
    	  now.
    	trigger BUG_ON()
    
    The message is following:
    btrfs allocation failed flags 1, wanted 4096
    space_info has 1040187392 free, is not full
    space_info total=1082130432, used=4096, pinned=41938944, reserved=0, may_use=40828928, readonly=0
    block group 12582912 has 8388608 bytes, 0 used 8388608 pinned 0 reserved
    block group has cluster?: no
    0 blocks of free space at or bigger than bytes is
    block group 1103101952 has 1073741824 bytes, 4096 used 33550336 pinned 0 reserved
    block group has cluster?: no
    0 blocks of free space at or bigger than bytes is
    ------------[ cut here ]------------
    kernel BUG at fs/btrfs/inode.c:835!
     [<ffffffffa031261b>] __extent_writepage+0x1bf/0x5ce [btrfs]
     [<ffffffff810cbcb8>] ? __set_page_dirty_nobuffers+0xfe/0x108
     [<ffffffffa02f8ada>] ? wait_current_trans+0x23/0xec [btrfs]
     [<ffffffff810c3fbf>] ? find_get_pages_tag+0x73/0xe2
     [<ffffffffa0312d12>] extent_write_cache_pages.clone.0+0x176/0x29a [btrfs]
     [<ffffffffa0312e74>] extent_writepages+0x3e/0x53 [btrfs]
     [<ffffffff8110ad2c>] ? do_sync_write+0xc6/0x103
     [<ffffffffa0302d6e>] ? btrfs_submit_direct+0x414/0x414 [btrfs]
     [<ffffffff811380fa>] ? fsnotify+0x236/0x266
     [<ffffffffa02fc930>] btrfs_writepages+0x22/0x24 [btrfs]
     [<ffffffff810cc215>] do_writepages+0x1c/0x25
     [<ffffffff810c4958>] __filemap_fdatawrite_range+0x4e/0x50
     [<ffffffff810c4982>] filemap_write_and_wait_range+0x28/0x51
     [<ffffffffa0306b2e>] btrfs_sync_file+0x7d/0x198 [btrfs]
     [<ffffffff8110aa26>] ? fsnotify_modify+0x5d/0x65
     [<ffffffff8112d150>] vfs_fsync_range+0x18/0x21
     [<ffffffff8112d170>] vfs_fsync+0x17/0x19
     [<ffffffff8112d316>] do_fsync+0x29/0x3e
     [<ffffffff8112d348>] sys_fsync+0xb/0xf
     [<ffffffff81468352>] system_call_fastpath+0x16/0x1b
    [SNIP]
    RIP  [<ffffffffa02fe08c>] cow_file_range+0x1c4/0x32b [btrfs]
    
    We fix this bug by trying to allocate the space again if there are block groups
    in caching.
    Signed-off-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
    60d2adbb
extent-tree.c 197 KB