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: sta...@vger.kernel.org # 4.5+
> Fixes: a5ed91828518 ("Btrfs: implement the free space B-tree")
> Signed-off-by: Josef Bacik <jo...@toxicpanda.com>

Added to misc-next with Filipe's review from v2, thanks.

Reply via email to