BTRFS boot failure and easy GUI methods for system recovery

Additional notes

The mechanism of system recovery was the main focus of the original article, and I wanted to write things down while my experiences and learning were still fresh and new in my mind.

With my need to get the article finished, I was constrained to place a certain amount of reliance on the official documents.

From extensive further research, there are now some additional observations and clarifications to make on maintenance and configuration.

Then there are the things that we just do automatically. It can be all too easy to forget to mention these important snippets. Power-save disabling is precisely one of those things.


Backup and partition adjustment

  • Make sure to DISABLE POWER-SAVE and screen lock features before attemping any of these procedures.

Idle time detectors won’t register what is happening. Discard any .img files that have had power supply or idle time interruptions. Even if they appear okay, they will usually contain hidden errors. Repeat any partition restores that have been interrupted too.


On the positive side, something to add is that Gparted is BTRFS aware. Remembering of course that any partition work is never 100% guaranteed, this does mean that Gparted should handle all the sub-volume adjustments. Tests that I have carried out on resizing show this to be the case. This works in both directions.

Snapper

I have now revised my auto-snapshot settings and discovered that man snapper-configs as well as excessive with its defaults, is not as clear as it could be either.

Working out that numbers only refers to the number of boot snapshots and reducing this figure from 50 to 5 saved an estimated 7 GiB of data space and reduced metadata usage by nearly 50%

BEFORE

@fedora:\~$ sudo btrfs fi us -b /

    Device size:                      153771573248

    Device allocated:                  96703873024

    Device unallocated:                57067700224

    Device missing:                              0

    Device slack:                       1073741824

    Used:                              84112801792

    Free (estimated):                  66286321664      (min: 37752471552)

    Free (statfs, df):                 66285273088

    Data ratio:                               1.00

    Metadata ratio:                           2.00

    Global reserve:                      319062016      (used: 0)

    Multiple profiles:                          no


Data,single: Size:83751862272, Used:74533240832 (88.99%)

   /dev/nvme1n1p5       83751862272


Metadata,DUP: Size:6442450944, Used:4789764096 (74.35%)

   /dev/nvme1n1p5       12884901888


@fedora:\~$ sudo btrfs fi du -s /.snapshots

     Total   Exclusive  Set shared  Filename

   1.31TiB    15.53GiB    39.51GiB  /.snapshots


@fedora:\~$ sudo ls /.snapshots | grep -e ^ -c

71

AFTER

@fedora:\~$ sudo snapper -v cleanup all

@fedora:\~$ sudo btrfs fi us -h /

    Device size:                 143.21GiB

    Device allocated:             90.06GiB

    Device unallocated:           53.15GiB

    Device missing:                  0.00B

    Device slack:                  1.00GiB

    Used:                         64.50GiB

    Free (estimated):             73.06GiB      (min: 46.49GiB)

    Free (statfs, df):            73.06GiB

    Data ratio:                       1.00

    Metadata ratio:                   2.00

    Global reserve:              302.62MiB      (used: 0.00B)

    Multiple profiles:                  no


Data,single: Size:78.00GiB, Used:58.09GiB (74.47%)

   /dev/nvme0n1p5         78.00GiB


Metadata,DUP: Size:6.00GiB, Used:3.21GiB (53.44%)

   /dev/nvme0n1p5         12.00GiB


@fedora:\~$ sudo btrfs fi du -s /.snapshots

     Total   Exclusive  Set shared  Filename

 485.31GiB    21.81GiB    23.52GiB  /.snapshots

@fedora:\~$ sudo snapper list -a

Config: home, subvolume: /home

  \# │ Type   │ Pre # │ Date                          │ User │ Cleanup  │ Description │ Userdata

────┼────────┼───────┼───────────────────────────────┼──────┼──────────┼─────────────┼─────────

  0 │ single │       │                               │ root │          │ current     │

153 │ single │       │ Sat 01 Aug 2026 12:00:05 CEST │ root │ timeline │ timeline    │

282 │ single │       │ Mon 31 Aug 2026 06:00:14 CEST │ root │ timeline │ timeline    │

291 │ single │       │ Tue 01 Sep 2026 08:00:01 CEST │ root │ timeline │ timeline    │

314 │ single │       │ Tue 08 Sep 2026 10:00:14 CEST │ root │ timeline │ timeline    │

330 │ single │       │ Mon 14 Sep 2026 08:00:30 CEST │ root │ timeline │ timeline    │

351 │ single │       │ Sun 20 Sep 2026 11:00:44 CEST │ root │ timeline │ timeline    │

356 │ single │       │ Mon 21 Sep 2026 09:00:03 CEST │ root │ timeline │ timeline    │

360 │ single │       │ Tue 22 Sep 2026 07:00:00 CEST │ root │ timeline │ timeline    │

365 │ single │       │ Tue 22 Sep 2026 13:00:07 CEST │ root │ timeline │ timeline    │

366 │ single │       │ Tue 22 Sep 2026 15:00:04 CEST │ root │ timeline │ timeline    │

367 │ single │       │ Wed 23 Sep 2026 09:00:17 CEST │ root │ timeline │ timeline    │

368 │ single │       │ Wed 23 Sep 2026 10:00:02 CEST │ root │ timeline │ timeline    │

369 │ single │       │ Wed 23 Sep 2026 11:00:52 CEST │ root │ timeline │ timeline    │

370 │ single │       │ Wed 23 Sep 2026 12:00:21 CEST │ root │ timeline │ timeline    │

371 │ single │       │ Thu 24 Sep 2026 10:00:10 CEST │ root │ timeline │ timeline    │

372 │ single │       │ Thu 24 Sep 2026 11:00:10 CEST │ root │ timeline │ timeline    │

373 │ single │       │ Thu 24 Sep 2026 12:00:04 CEST │ root │ timeline │ timeline    │

374 │ single │       │ Fri 25 Sep 2026 11:00:01 CEST │ root │ timeline │ timeline    │

375 │ single │       │ Fri 25 Sep 2026 12:00:08 CEST │ root │ timeline │ timeline    │

376 │ single │       │ Fri 25 Sep 2026 13:00:08 CEST │ root │ timeline │ timeline    │


Config: root, subvolume: /

  \# │ Type   │ Pre # │ Date                          │ User │ Cleanup  │ Description │ Userdata

────┼────────┼───────┼───────────────────────────────┼──────┼──────────┼─────────────┼─────────

  0 │ single │       │                               │ root │          │ current     │

242 │ single │       │ Sat 01 Aug 2026 12:00:05 CEST │ root │ timeline │ timeline    │

460 │ single │       │ Mon 31 Aug 2026 06:00:14 CEST │ root │ timeline │ timeline    │

472 │ single │       │ Tue 01 Sep 2026 08:00:01 CEST │ root │ timeline │ timeline    │

512 │ single │       │ Tue 08 Sep 2026 10:00:14 CEST │ root │ timeline │ timeline    │

542 │ single │       │ Mon 14 Sep 2026 08:00:30 CEST │ root │ timeline │ timeline    │

581 │ single │       │ Sun 20 Sep 2026 11:00:44 CEST │ root │ timeline │ timeline    │

589 │ single │       │ Mon 21 Sep 2026 09:00:03 CEST │ root │ timeline │ timeline    │

597 │ single │       │ Tue 22 Sep 2026 07:00:00 CEST │ root │ timeline │ timeline    │

605 │ single │       │ Tue 22 Sep 2026 13:00:07 CEST │ root │ timeline │ timeline    │

607 │ single │       │ Tue 22 Sep 2026 15:00:04 CEST │ root │ timeline │ timeline    │

610 │ single │       │ Wed 23 Sep 2026 09:00:17 CEST │ root │ timeline │ timeline    │

612 │ single │       │ Wed 23 Sep 2026 10:00:02 CEST │ root │ timeline │ timeline    │

613 │ single │       │ Wed 23 Sep 2026 11:00:52 CEST │ root │ timeline │ timeline    │

614 │ single │       │ Wed 23 Sep 2026 12:00:21 CEST │ root │ timeline │ timeline    │

615 │ single │       │ Thu 24 Sep 2026 09:03:46 CEST │ root │ number   │ boot        │

616 │ single │       │ Thu 24 Sep 2026 09:07:44 CEST │ root │ number   │ boot        │

617 │ single │       │ Thu 24 Sep 2026 10:00:11 CEST │ root │ timeline │ timeline    │

618 │ single │       │ Thu 24 Sep 2026 11:00:10 CEST │ root │ timeline │ timeline    │

619 │ single │       │ Thu 24 Sep 2026 11:48:05 CEST │ root │ number   │ boot        │

620 │ single │       │ Thu 24 Sep 2026 12:00:04 CEST │ root │ timeline │ timeline    │

621 │ single │       │ Fri 25 Sep 2026 10:57:16 CEST │ root │ number   │ boot        │

622 │ single │       │ Fri 25 Sep 2026 10:59:58 CEST │ root │ number   │ boot        │

623 │ single │       │ Fri 25 Sep 2026 11:00:01 CEST │ root │ timeline │ timeline    │

624 │ single │       │ Fri 25 Sep 2026 12:00:08 CEST │ root │ timeline │ timeline    │

625 │ single │       │ Fri 25 Sep 2026 13:00:08 CEST │ root │ timeline │ timeline    │
@fedora:\~$ sudo snapper list -a | grep number

615 │ single │       │ Thu 24 Sep 2026 09:03:46 CEST │ root │ number   │ boot        │

616 │ single │       │ Thu 24 Sep 2026 09:07:44 CEST │ root │ number   │ boot        │

619 │ single │       │ Thu 24 Sep 2026 11:48:05 CEST │ root │ number   │ boot        │

621 │ single │       │ Fri 25 Sep 2026 10:57:16 CEST │ root │ number   │ boot        │

622 │ single │       │ Fri 25 Sep 2026 10:59:58 CEST │ root │ number   │ boot        │

Note also that boot snaps are only on the root sub-volume and that records of /home are only timeline or manual

Btrfs balance

Looking at, and on reflecting on, the btrfs docs my feeling is that the term balance must have been coined at a time when RAID HDD’s needed to be striped to get faster parallel output of the same file from two drives.

We now want SSD’s in duplicate to cover against drive failure. RAID 1 is now the default.

Although I intially referenced the official documents, my feeling is now that the balance notes are out-of-date and have become somewhat misleading.

The term balance has to now be seen in the framework of general system equilbrium rather than as a method of getting an equal and balanced amount of data onto a parallel pair of drives. Either that or the term should be deprecated and a new one given, like repack, consolidate or reallocate.


I now RECOMMEND putting the btrfs assistant balance setting at weekly

On an SSD with a 150 GiB main partition, the automated -dusage=10 routine takes just over 1 whole second …

For a manual space-defragmentation use sudo btrfs -v balance start -dusage=40 -musage=5 /

No more than -dusage=50 -musage=10


In simple terms, try to imagine that the file system divides up and pre-allocates data blocks on the drive. The data gets written to a convenient block and its position and percentage occupancy of the block is recorded by the metadata. A bit like stacking things in boxes and then labeling them.

The metadata blocks need plenty of free space in them to be unimpeded when recording data changes. Compacting these beyond =10 will have negative effects when the disk is getting full. The number of metadata blocks will auto-adjust, depending on drive size and usage, and on the number of snapshots.

Some blocks are full, others only partly. When we balance the drive’s equilibrium, we look for blocks that are somewhat empty and try to fill them up with bits and bobs from somewhere else. This makes the free space less fragmented, easier to write to and easier to measure.

We don’t need to set the data usage filter to any greater than =50 as we can’t fit two blocks with greater than 50% usage in together with each other.

On tests carried out on repeated-roll-back identical state virtual machines, btrfs balance start -dusage=42 -musage=8 / and btrfs-balance-least-used -u 42 / were almost identical.

Repeat START POINT:

sudo btrfs fi df /

Data, single: total=26.01GiB, used=22.02GiB

Metadata, DUP: total=3.00GiB, used=1.68GiB

sudo time -f %E  btrfs balance start -dusage=42 -musage=8 /

Done, had to relocate 3 out of 31 chunks

0:01.31


sudo btrfs fi df /

Data, single: total=24.01GiB, used=22.03GiB

Metadata, DUP: total=3.00GiB, used=1.68GiB

sudo time -f %E btrfs-balance-least-used -u 42 /

Loading block group objects with used_pct <= 42 ... found 2

Balance block group vaddr 32477544448 used_pct 15 ... duration 0 sec total 31

Balance block group vaddr 28182577152 used_pct 30 ... duration 0 sec total 30

0:01.04


btrfs fi df /

Data, single: total=24.01GiB, used=22.23GiB

Metadata, DUP: total=3.00GiB, used=1.68GiB

Running as high as btrfs-balance-least-used -u 80 / achieved no more space compaction.


On the Snapper 50 to 5 number reduction:

BEFORE

sudo btrfs fi us -h /

    Device size:                 143.21GiB

    Device allocated:             90.06GiB

    Device unallocated:           53.15GiB

    Device missing:                  0.00B

    Device slack:                  1.00GiB

    Used:                         64.50GiB

    Free (estimated):             73.06GiB      (min: 46.49GiB)

    Free (statfs, df):            73.06GiB

    Data ratio:                       1.00

    Metadata ratio:                   2.00

    Global reserve:              302.62MiB      (used: 0.00B)

    Multiple profiles:                  no


Data,single: Size:78.00GiB, Used:58.09GiB (74.47%)

   /dev/nvme0n1p5         78.00GiB


Metadata,DUP: Size:6.00GiB, Used:3.21GiB (53.44%)

   /dev/nvme0n1p5         12.00GiB


AFTER

sudo btrfs balance start -dusage=50 -musage=5 /

Done, had to relocate 4 out of 79 chunks


sudo btrfs fi us -h /

    Device size:                 143.21GiB

    Device allocated:             81.06GiB

    Device unallocated:           62.15GiB

    Device missing:                  0.00B

    Device slack:                  1.00GiB

    Used:                         64.50GiB

    Free (estimated):             73.06GiB      (min: 41.98GiB)

    Free (statfs, df):            73.06GiB

    Data ratio:                       1.00

    Metadata ratio:                   2.00

    Global reserve:              251.22MiB      (used: 0.00B)


Data,single: Size:69.00GiB, Used:58.09GiB (84.19%)

   /dev/nvme0n1p5         69.00GiB


Metadata,DUP: Size:6.00GiB, Used:3.21GiB (53.44%)

   /dev/nvme0n1p5         12.00GiB

Note the Free (estimated): 73.06GiB and Used: 64.50GiB remain identical. The defragmented space gives a higher MIN free space estimate but the actual free space remains the same.

Resize

Something to note here on the last before/after is the Device slack: 1.00GiB

All SSD’s should be setup with spare unallocated space around the partions. This allows the firmware to trim bad sectors and keep the drive healthy.

I decided to use the command sudo btrfs filesystem resize -1G / to add a bit of breathing room on the actual partition itself. I am not sure if BTRFS will use this automatically. The docs say that it will use unallocated space in a tight squeeze but whether that means device or volume unallocated is not clear. Irrespectively, I thought at least it could help with an enospc situation.

HDD’s

Users that are still running on rotational devices may need to consider using manual only settings for SCRUB

RAID

The Fedora installer will automatically use mkfs.btrfs defaults when two drives are given as targets and will create RAID 1 which creates duplicate (mirrored) disks.

1 Like