To understand what's going on here, you need to first understand that BTRFS uses a two-stage allocator. The first stage allocates large chunks of space (actually called 'chunks' in most of the documentation) which get used for exactly one type of allocation, either data (used for the data in files only), metadata (things like file names, directory structure, access times, ownership, permissions, etc), or system (used solely to store data about chunk allocations). Once a chunk has been allocated, the space in that chunk can only be freed by moving all the data out of it.
So, what exactly does this mean in terms of your filesystem?
Well, your output from btrfs filesystem df
shows the following:
Data, RAID1: total=446.12GiB, used=133.29GiB
System, RAID1: total=8.00MiB, used=80.00KiB
Metadata, RAID1: total=1.00GiB, used=609.05MiB
GlobalReserve, single: total=405.53MiB, used=0.00B
The total
values indicate how much space has been allocated to that type of chunk, while the used
value shows how much space is in use within those chunks. In your case, you have 446.32GB of space allocated to data chunks (almost the whole disk based on regular df
and btrfs filesystem show
output), but only 133.29GB of that space is actually in use. Given this and the symptoms described, BTRFS is trying to allocate a metadata chunk but has no space to do so (because all the free space is inside already allocated chunks), so you're just getting an error instead.
To recover from this, you'll have to run a balance. A balance quite literally sends all the data from selected chunks (or all of them if you pass no options) back through the allocator, which has the net effect of freeing up empty or mostly empty chunks because it packs things back into partially full chunks.
I would start with:
btrfs balance start -dusage=0 /mnt/ssd
That will remove all data chunks that have no actual data in them, which may be enough to get things working again for now, but will still leave you vulnerable to the same problem in the future.
To help compact things completely, repeat the above command with increasing values for the -dusage
option. I usually bump it by 5 each time up to about 50 (past 50, you're usually wasting time). The usage filter (specified above for just processing data chunks) will tell balance to select chunks that are only at most that percentage full, so by incrementally stepping it up bit by bit, you can more easily compact things without running into other issues.
You can help head off issues like this in the future by running something like the following regularly (I usually run it daily on my systems):
btrfs balance start -dusage=25 -dlimit=10 -musage=25 -mlimit=10 /mnt/ssd
That will balance the first 10 data and metadata chunks that are less than one quarter full, which should complete in a few seconds in most cases.