On Fri, Jan 15, 2021 at 04:26:17PM -0500, Josef Bacik wrote: > While running btrfs/011 in a loop I would often ASSERT() while trying to > add a new free space entry that already existed, or get an -EEXIST while > adding a new block to the extent tree, which is another indication of > double allocation. > > This occurs because when we do the free space tree population, we create > the new root and then populate the tree and commit the transaction. > The problem is when you create a new root, the root node and commit root > node are the same. During this initial transaction commit we will run > all of the delayed refs that were paused during the free space tree > generation, and thus begin to cache block groups. While caching block > groups the caching thread will be reading from the main root for the > free space tree, so as we make allocations we'll be changing the free > space tree, which can cause us to add the same range twice which results > in either the ASSERT(ret != -EEXIST); in __btrfs_add_free_space, or in a Still no stacktraces but at least this gives some pointer to the code which assert is hit. > variety of different errors when running delayed refs because of a > double allocation. > > Fix this by marking the fs_info as unsafe to load the free space tree, > and fall back on the old slow method. We could be smarter than this, > for example caching the block group while we're populating the free > space tree, but since this is a serious problem I've opted for the > simplest solution. > > CC: stable@xxxxxxxxxxxxxxx # 4.5+ > Fixes: a5ed91828518 ("Btrfs: implement the free space B-tree") > Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx> Added to misc-next with Filipe's review from v2, thanks.