btrfs: set cache_block_group_error if we find an error

We set cache_block_group_error if btrfs_cache_block_group() returns an
error, this is because we could end up not finding space to allocate and
mistakenly return -ENOSPC, and which could then abort the transaction
with the incorrect errno, and in the case of ENOSPC result in a
WARN_ON() that will trip up tests like generic/475.

However there's the case where multiple threads can be racing, one
thread gets the proper error, and the other thread doesn't actually call
btrfs_cache_block_group(), it instead sees ->cached ==
BTRFS_CACHE_ERROR. Again the result is the same, we fail to allocate
our space and return -ENOSPC. Instead we need to set
cache_block_group_error to -EIO in this case to make sure that if we do
not make our allocation we get the appropriate error returned back to
the caller.

CC: stable@vger.kernel.org # 4.14+
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>

authored by Josef Bacik and committed by David Sterba 92fb94b6 6ebcd021

Changed files
+4 -1
fs
+4 -1
fs/btrfs/extent-tree.c
··· 4310 4310 ret = 0; 4311 4311 } 4312 4312 4313 - if (unlikely(block_group->cached == BTRFS_CACHE_ERROR)) 4313 + if (unlikely(block_group->cached == BTRFS_CACHE_ERROR)) { 4314 + if (!cache_block_group_error) 4315 + cache_block_group_error = -EIO; 4314 4316 goto loop; 4317 + } 4315 4318 4316 4319 if (!find_free_extent_check_size_class(ffe_ctl, block_group)) 4317 4320 goto loop;