mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 14:42:24 +00:00
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:
parent
2bb2e00ed9
commit
ecd84d5467
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user