btrfs: update comments for chunk allocation -ENOSPC cases

Update the comments at btrfs_chunk_alloc() and do_chunk_alloc() that
describe which cases can lead to a failure to allocate metadata and system
space despite having previously reserved space. This adds one more reason
that I previously forgot to mention.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Filipe Manana 2021-10-13 10:12:50 +01:00 committed by David Sterba
parent 2bb2e00ed9
commit ecd84d5467
1 changed files with 18 additions and 3 deletions

View File

@ -3429,7 +3429,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags)
/*
* Normally we are not expected to fail with -ENOSPC here, since we have
* previously reserved space in the system space_info and allocated one
* new system chunk if necessary. However there are two exceptions:
* new system chunk if necessary. However there are three exceptions:
*
* 1) We may have enough free space in the system space_info but all the
* existing system block groups have a profile which can not be used
@ -3455,7 +3455,14 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags)
* with enough free space got turned into RO mode by a running scrub,
* and in this case we have to allocate a new one and retry. We only
* need do this allocate and retry once, since we have a transaction
* handle and scrub uses the commit root to search for block groups.
* handle and scrub uses the commit root to search for block groups;
*
* 3) We had one system block group with enough free space when we called
* check_system_chunk(), but after that, right before we tried to
* allocate the last extent buffer we needed, a discard operation came
* in and it temporarily removed the last free space entry from the
* block group (discard removes a free space entry, discards it, and
* then adds back the entry to the block group cache).
*/
if (ret == -ENOSPC) {
const u64 sys_flags = btrfs_system_alloc_profile(trans->fs_info);
@ -3539,7 +3546,15 @@ out:
* properly, either intentionally or as a bug. One example where this is
* done intentionally is fsync, as it does not reserve any transaction units
* and ends up allocating a variable number of metadata extents for log
* tree extent buffers.
* tree extent buffers;
*
* 4) The task has reserved enough transaction units / metadata space, but right
* before it tries to allocate the last extent buffer it needs, a discard
* operation comes in and, temporarily, removes the last free space entry from
* the only metadata block group that had free space (discard starts by
* removing a free space entry from a block group, then does the discard
* operation and, once it's done, it adds back the free space entry to the
* block group).
*
* We also need this 2 phases setup when adding a device to a filesystem with
* a seed device - we must create new metadata and system chunks without adding