BTRFS Filesystem Maintenance Automation with btrfsmaintenance Package

btrfsmaintenance

This post covers setup of the btrfsmaintenance package to automate sensible and recommended filesystem maintenance tasks of the btrfs filesystem. The common use case covered here is a single btrfs root filesystem mounted at /. This is the expected use case which allows a user to use the Storage Snapshots app built into Freedombox. A user using a more complex btrfs configuration such as a non-root btrfs or multiple btrfs filesystems is expected to be able to adapt these notes to their situation.

This does not apply to other filesystems such as ext4.

You will be able to schedule BTRFS filesystem maintenance tasks, confirm their future execution times, and observe that they have been completed using Cockpit and the system journal.

Does this apply to my freedombox?

The mount command will tell you the filesystem type (btrfs, ext4, etc.) you are using. you can run this command as an ordinary user:

mount | grep btrfs

The output will contain a line such as this if you are using btrfs:

/dev/sde3 on / type btrfs (rw,relatime,space_cache,subvolid=5,subvol=/)

If there is no output from the command you are not using btrfs and this post will not apply to your FreedomBox.

References

Configuration Files:

  • /etc/default/btrfsmaintenance

Goals

We will use the btrfsmaintenance package to automate sensible filesystem maintenance tasks and communicate diagnostic messages to the journal. Available tasks are:

  • scrub should be run periodically on all btrfs filesystems and we will schedule this monthly.
  • defrag is helpful for mechanical disk users as btrfs copy-on-write (COW) will create fragmented files which increase hard drive seeking which reduces performance. Solid state devices do not seek, but may still see a benefit from reduced metadata size.
  • balance is appropriate for btrfs volumes having multiple storage devices, but is not frequently (if ever) necessary. This can be run manually when needed, but even a monthly schedule may be too frequent.
  • trim is an operation used with solid state storage devices which marks unused cells as inactive and can increase device life.

Install btrfsmaintenance

btrfsmaintenance is part of Debian and may be installed from apt:
sudo apt install btrfsmaintenance

Configure btrfsmaintenance

btrfsmaintenance will not be report to the journal on installation and no maintenance tasks will be scheduled. We will modify the /etc/default/btrfsmaintenance configuration file to create the desired behavior. Btrfsmaintenance-refresh service will need to be restarted to enable changes to the configuration file. All changed configuration keys will be in bold.

Enabling btrfsmaintenance configuration changes

You may restart the service with this command:
sudo systemctl restart btrfsmaintenance-refresh

Report messages to the journal

We change the BTRFS_LOG_OUTPUT key to use the systemd journal.

## Path: System/File systems/btrfs
## Type: string(none,stdout,journal,syslog)
## Default: “stdout”
#
# Output target for messages. Journal and syslog messages are tagged by the task name like
# ‘btrfs-scrub’ etc.
BTRFS_LOG_OUTPUT=“journal”

Enable defragmentation

Defragment is does not have a default period set, so we will select monthly to be conservative. There are different recommendations for mechanical disk versus solid state devices.

Mechanical Disks

We change the BTRFS_DEFRAG keys to enable monthly defragmentation.

## Path: System/File systems/btrfs
## Type: string(none,daily,weekly,monthly)
## Default: “none”
## ServiceRestart: btrfsmaintenance-refresh
#
# Frequency of defrag.
BTRFS_DEFRAG_PERIOD=“monthly”

Restart the service and observe a defrag message after the first of the month in the journal.

Solid state devices such as SD Card, SSD, nvme…

Solid state devices will not benefit from defrag in the same way as for mechanical disks owing to the fact that solid state devices do not seek. Seeking is the act of changing the spindle position in a mechanical disk to the appropriate track and then waiting for the rotation of the disk to present the desired blocks to the spindle for reading. Defrag solid state devices manually if needed. You may see a benefit on a filesystem which has been operational for months or years and when you are starting to feel some storage capacity pressure. I would not expect this to solve your storage capacity issue, but it appears that it can help somewhat by reducing the size of metadata. There will be many metadata entries to locate each fragment of a fragmented file - so this reduces the metadata load. Here is a manual defragment command:

sudo btrfs filesystem defragment -r /

I would not schedule this on a solid state device to avoid unnecessary wear on the device.

Balance - let’s not schedule that.

Users having multiple devices for a btrfs filesystem may wish to run the balance operation when the devices are not being used about equally. Balancing happens automatically with btrfs, but you should balance if you add or replace a device. Confirm that you see BTRFS_BALANCE_PERIOD=“none”.

## Path: System/File systems/btrfs
## Type: string(none,daily,weekly,monthly)
## Default: “none”
## ServiceRestart: btrfsmaintenance-refresh
#
# Frequency of periodic balance. Periodic balance is not required,
# nor useful, in most cases. Cases where it is beneficial should be
# reported upstream.
#
# The frequency may be specified using one of the listed values or
# in the format documented in the “Calendar Events” section of systemd.time(7),
# if available.
BTRFS_BALANCE_PERIOD=“none”

We can check to see if a balance is appropriate…
$sudo btrfs filesystem show /
Label: ‘sdc btrfs’ uuid: 0877d8d1-c66e-49dc-8b26-53ee22faadf6
Total devices 5 FS bytes used 941.10GiB
devid 1 size 435.03GiB used 0.00B path /dev/sde3
devid 2 size 3.64TiB used 527.03GiB path /dev/sda1
devid 3 size 3.64TiB used 527.03GiB path /dev/sdb1
devid 5 size 3.64TiB used 526.00GiB path /dev/sdd
devid 6 size 3.64TiB used 526.00GiB path /dev/sdc

Here we see that there are five disks:

  • devid 1 of 500GB
  • devid 2-6 of 4TB (skipping devid4 which failed in the past)

The five disks are a BTRFS Raid 1 and we see that data is equally distributed across the 4TB disks with 526-527 GB per disk. This is balanced. btrfs is not using the capacity on the 500GB drive, and that’s okay in this case as the filesystem is creating two copies of every file on equally sized disks. No balance is needed here. If there were a disk with unequal usage (such as a new or replacement disk) then balance would be in order and is done like this:

sudo btrfs-balance start --background /

This operation will take time and create a high I/O load while it runs. You can monitor progress with:
sudo btrfs-balance status /

Alternatively, if you read the configuration file closely you an schedule balance to run conditionally with the BTRFS_BALANCE_DUSAGE and BTRFS_BALANCE_MUSAGE keys and maybe start with the defaults.

Enable scrub

Scrub is recommended for everybody. It is not an fsck, but you can think of it this way. The scrub page in the wiki explains this. Do this monthly (which appears to be the default). You may not need to change this, but do confirm that this is scheduled monthly.

## Path: System/File systems/btrfs
## Type: string(none,weekly,monthly)
## Default: “monthly”
## ServiceRestart: btrfsmaintenance-refresh
#
# Frequency of periodic scrub.
#
# The frequency may be specified using one of the listed values or
# in the format documented in the “Calendar Events” section of systemd.time(7),
# if available.
BTRFS_SCRUB_PERIOD=“monthly”

## Path: System/File systems/btrfs
## Type: string(idle,normal)
## Default: “idle”
#
# Priority of IO at which the scrub process will run. Idle should not degrade
# performance but may take longer to finish.
BTRFS_SCRUB_PRIORITY=“idle”

## Path: System/File systems/btrfs
## Type: boolean
## Default: “false”
#
# Do read-only scrub and don’t try to repair anything.
BTRFS_SCRUB_READ_ONLY=“false”

Enable trim for solid state devices such as SD Card, SSD, nvme…

Trim will deactivate memory cells in the solid state device which will reduce wear and increase device life. This is not needed for mechanical disks. Weekly is recommended.

## Path: System/File systems/btrfs
## Description: Configuration for periodic fstrim
## Type: string(none,daily,weekly,monthly)
## Default: “none”
## ServiceRestart: btrfsmaintenance-refresh
#
# Frequency of periodic trim. Off by default so it does not collide with
# fstrim.timer . If you do not use the timer, turn it on here. The recommended
# period is ‘weekly’.
#
# The frequency may be specified using one of the listed values or
# in the format documented in the “Calendar Events” section of systemd.time(7),
# if available.
BTRFS_TRIM_PERIOD=“weekly”

## Path: System/File systems/btrfs
## Description: Configuration for periodic fstrim - mountpoints
## Type: string
## Default: “/”
#
# Which mountpoints/filesystems to trim periodically.
# (Colon separated paths)
# The special word/mountpoint “auto” will evaluate all mounted btrfs
# filesystems
BTRFS_TRIM_MOUNTPOINTS=“/”

Leave concurrency off

The default is to disable concurrent operations so you are not trying to balance, defrag, and scrub all at the same time. This seems prudent. Confirm this is the case.

## Path: System/File systems/btrfs
## Description: Configuration to allow concurrent jobs
## Type: boolean
## Default: “false”
#
# These maintenance tasks may compete for resources with each other, blocking
# out other tasks from using the file systems. This option will force
# these jobs to run in FIFO order when scheduled at overlapping times. This
# may include tasks scheduled to run when a system resumes or boots when
# the timer for these tasks(s) elapsed while the system was suspended
# or powered off.
BTRFS_ALLOW_CONCURRENCY=“false”

Enable your changes

If you have made one or more changes to the configuration file don’t forget to restart the service:
sudo systemctl restart btrfsmaintenance-refresh

Check the service timers to see that the tasks are scheduled

Using the Cockpit Services app you can look at the timers and see that your btrfsmaintenance tasks are scheduled. In this case several are scheduled for the same moment, but I’ll rely on the BTRFS_ALLOW_CONCURRENCY=“false” statement to prevent them from running at the same time.

Check the journal after the tasks should have run

Using Cockpit check the logs searching for priority “Info and above” and filter for “btrfs”. You will see that the scheduled tasks were executed as expected.

5 Likes

Scheduling BTRFS Trim is now redundant in Trixie for new filesystems.

If you upgraded to Trixie you may wish to double check this.

There is some new information on btrfs trim shared with me by PM here from an astute user…

The important detail is this

When a filesystem is created by mkfs.btrfs(8) and is capable of trim, then it’s by default performed on all devices. Since kernel 6.2 the discard=async mount option is automatically enabled on devices that support that.

I see my laptop filesystem has this option set…

$mount
/dev/nvme0n1p3 on / type btrfs (rw,relatime,ssd,discard=async,space_cache=v2,subvolid=256,subvol=/@rootfs)

… so while it is still good to use btrfsmaintenance to schedule a scrub operation, there is no longer a need to schedule trim. The filesystem defaults now have an automatic trim operation that runs once a collection of trim operations are queued up.

If you use a SSD, SD Card, NVME device you can schedule scrub with btrfsmaintenance. If you use a spinny disk you can also schedule a defrag. You can let btrfs handle the trim operation by default.

If you upgraded your system to Trixie

Check your mount options for your btrfs filesystems with the mount command shown above. This applies to you if you use SSD/SD Card/NVME and does not apply for mechanical disks. If you do not see discard=async you may continue to use the scheduled trim operation. If you see the discard=async option then you no longer need to use the scheduled trim.

To unschedule trim change the BTRFS_TRIM_PERIOD to “none”.

If you have the discard=async option and you also leave your trim operation scheduled with btrfsmaintenance that is not going to hurt anything. You could just leave it as is.

3 Likes

Autodefrag mount option exists today.

This applies to mechanical disk users. Filesystem defragmentation is recommended owing to the copy-on-write nature of btrfs discussed above. You don’t need this with SSD/nvme/SD card storage. I see two options.

  • Schedule defragmentation with btrfsmaintenance as shown above
  • Enable an autodefrag mount option to the filesystem

I post this mostly for interest after being directed to the automatic filesystem trim mount option.

The safer choice will be to schedule defragmentation with btrfsmaintenance as shown above. If you care about performance during defragmentation you have the ability to shift the schedule to a quiet period when you don’t use FreedomBox. It’s completely okay to just use defaults which is what I do. Further, if you care about performance you’ll probably prefer to not incur an ongoing performance cost from automatic defragmentation.

There is a mount option that will enable automatic defragmentation on a file-by-file basis. In my opinion there are some down sides to using this:

  • There is a risk to editing fstab, you have to get this exactly right and it could prevent FreedomBox from booting if you get it wrong.
  • There is some ongoing performance penalty, which is probably not even noticeable for us to using this option. The exception noted in documentation is “large database workloads.”

I’m going to continue using the schedule. File fragmentation isn’t going to be much of a problem except with a full disk and long periods without defragmentation. Keeping up with it monthly using the btrfsmaintenance schedule looks like the best choice for me.

It does not appear that this option would be enabled by default for a new filesystem in the same manner where the discard option would be set by btrfs for a new filesystem.