diff options
| author | Boris Burkov <boris@bur.io> | 2026-09-28 17:20:33 -0700 |
|---|---|---|
| committer | David Sterba <dsterba@suse.com> | 2026-10-12 19:16:23 +0200 |
| commit | cd5e2d2f2ea2b2c644ac8a01b50a8f22bd23610f (patch) | |
| tree | 1ce4d835f58c3ed7814e092bc606200271bd9587 /tools/perf/scripts/python/flamegraph.py | |
| parent | d658eb2bda4c67836cf49a88c082b3719258f814 (diff) | |
| download | linux-cd5e2d2f2ea2b2c644ac8a01b50a8f22bd23610f.tar.gz linux-cd5e2d2f2ea2b2c644ac8a01b50a8f22bd23610f.zip | |
btrfs: allocate additional SYSTEM space earlier
Currently, reserve_chunk_space() allocates a new system chunk when the
space left is smaller than the reservation for a single chunk tree
update.
Therefore, a filesystem in single metadata mode on a very large block
device can accumulate tens of thousands (TB) of chunks while never
allocating more than the original 4MiB SYSTEM block group created by
mkfs. If it then fills up (with large fallocates for example) and then
that data is freed, en-masse, we end up trying to delete thousands of
block groups in a single transaction in btrfs_delete_unused_bgs().
This process touches most of the nodes and leaves of the chunk tree,
essentially trying to allocate roughly double the current usage of the
chunk tree for cow. When this runs into needing a fresh system chunk,
the fs is full of the empty bgs and we abort with ENOSPC in
btrfs_remove_chunk() like:
BTRFS error (device loop0 state A): Transaction 30733 aborted (-ENOSPC)
space_info SYSTEM (sub-group id 0) has 0 free, is not full
space_info total=4194304, used=3276800, pinned=0, reserved=917504, may_use=0, readonly=0 zone_unusable=0
BTRFS: error (device loop0 state A) in btrfs_remove_chunk:3643: errno=-28 No space left
This was seen on a 30TiB production filesystem with 10TiB of unused
block groups and reproduces on a 30TiB sparse loop device: mkfs with
-m single, fallocate 1GiB files until ENOSPC, delete two of every three
adjacent files, sync.
To fix this, we should allocate the (relatively tiny) system chunks a
little bit more eagerly. If we do it when it is half full, we ensure we
can delete all of the block groups in one go. To fill up half of a 4MiB
system bg requires thousands of block_groups so this should only affect
very large fileystems.
Assisted-by: LLM
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Boris Burkov <boris@bur.io>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'tools/perf/scripts/python/flamegraph.py')
0 files changed, 0 insertions, 0 deletions
