Personal Notes about Brtfs
This page is use to note personal notes about Btrfs, with the aim to include some in official pages.
I (RobertCheramy) am trying to collect the missing information when I searched information about Btrfs.
Status
The official Status of Btrfs is for the latest Kernel only.
Debian stable uses an older kernel, so you need to look at older status pages:
For Bookworm (kernel 6.1), the status is in the old wiki of btrfs (Kernel 6.0)
For Trixie (kernel 6.12), the status is in the history of btrfs documentation for 6.12.
Note: the Kernel status could not be the Debian status, as it may depend from third party tools or conservative recommendations.
Table of contents:
Contents
Recommended configuration for a home NAS server
TODOs
install samba & set up users & passwords
Overview
This recommended configuration follows following premises:
- Make it as simple as possible
- Use to safe options
- Work on debian stable (currently: bookworm)
- You are a "normal" user who knows how to install a debian system and administrate it from the command line.
- "Advanced" user can use more specific parameters and options. These are off topic here.
Hardware setup
The hardware used to write this article is a Ugreen NASync DXP2800 with one NVMe SSD and two Seagate ?IronWolf NAS CMR rotational disks.
- You can use on any hardware, the NVMe SSD is optional, and can be replaced with dedicated partitions on the rotational disks.
- Make sure you use CMR rotational disks dedicated for NAS usage.
Targeted functions
- Safely store family memories and data on CMR rotational disks. Survive one disk failure and take care of silent corruption of the data on the disks.
- Be informed about problems on your mailbox.
- Share this data per samba in the local network. Have different users for different data.
- Backup home desktops and laptops on the NAS
- Run advanced functions natively or in podman containers (gitlab, immich...)
Parameters
- The efi boot partition is not redundant and stored on the NVMe
- reason: efi needs FAT32.
- If your disk fails, restore from backups
- The root partition is not redundant, ext4 and stored on the NVMe
- reason: apt is slow on btrfs
- reason: podman is better run on an ext4 partition [avoid COW on COW, avoid fragmentation]
- If your disk fails, restore from backups
- The swap partition is not redundant and stored on the NVMe
- Each CMR rotational disk get one big btrfs partition with exactly the same size and position on the disk (/dev/sda1 and /dev/sdb2).
- reason: btrfs brings availability with raid1 and data integrity against silent corruption
- For storing the data, family memories and backups
- The data will be separated in subvolumes
Installation of the basic Debian system
Install Debian on the NVMe. use one partition for everything (/, /usr, /var, /home...). Do not install a GUI (gnome, kde...), install the ssh-server.
Install packages for btrfs:
apt install btrfs-progs btrfsmaintenance
Install a mailserver. A good option is postfix with the configuration type "Satellite system". Make sure emails to root get send to you (edit /etc/aliases, add root: you@email.com, run newaliases
Install mailutils so that the tools cand send emails to root.
You may want to install rsyslog and lnav if you are an old school /var/log/syslog user
Install unattended-upgrades to keep your debian server updated in the background. Edit /etc/apt/apt.conf.d/50unattended-upgrades , and uncomment/modify following parameter (read the comment above each parameter and only follow the recommendation if it is OK for you):
// You can change root with your email. Unattended-Upgrade::Mail "root"; Unattended-Upgrade::MailReport "on-change"; Unattended-Upgrade::Automatic-Reboot "true"; Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
Install smartmontools to monitor your disks (and get an email in case of problems).
btrfs on the rotational disks
Set up the btrfs partition
root@ulm:~# mkfs.btrfs /dev/sda1 /dev/sdb1 -m raid1 -d raid1 -L btrfs-data
btrfs-progs v6.2
See http://btrfs.wiki.kernel.org for more information.
Performing full device TRIM /dev/sdb1 (498.00MiB) ...
Performing full device TRIM /dev/sda1 (498.00MiB) ...
NOTE: several default settings have changed in version 5.15, please make sure
this does not affect your deployments:
- DUP for metadata (-m dup)
- enabled no-holes (-O no-holes)
- enabled free-space-tree (-R free-space-tree)
Label: btrfs-data
UUID: e8b50d90-0e20-45ec-a153-a725e074f306
Node size: 16384
Sector size: 4096
Filesystem size: 996.00MiB
Block group profiles:
Data: RAID1 64.00MiB
Metadata: RAID1 49.75MiB
System: RAID1 8.00MiB
SSD detected: no
Zoned device: no
Incompat features: extref, skinny-metadata, no-holes
Runtime features: free-space-tree
Checksum: crc32c
Number of devices: 2
Devices:
ID SIZE PATH
1 498.00MiB /dev/sda1
2 498.00MiB /dev/sdb1Explanations:
-m raid1 -d raid1 : always store metadada and data on two separate partitions.
-L btrfs-data : give the partition a name, so we can see it under /dev/disk/by-label/
- Note the provided UUID, we will need it to mount the disk in /etc/fstab
Mount the btrfs partition
The btrfs partition is only needed for administrative tasks, we will create and mount subvolumes to work with data.
mkdir /btrfs-admin mount /dev/disk/by-label/btrfs-data /btrfs-admin/ -o noatime chmod 0700 /btrfs-admin/
Explanations:
-o noatime tells the filesystem not to store when a file was accessed. This produces overhead, and very few people care about the access-time.
chmod 0700 /btrfs-admin/ this is only for administration, not for accessing the data
Create subvolumes
The btrfs partition will be segmented in subvolumes. The subvolumes will be mounted separately, but share the same partition and disk space. For this example, we will create three subvolumes:
- @data - data shared by the whole family
- @scan - for saving scanned documents
- @backups - for backups
The subvolumes begin with @, so that we do not confuse them with normal directories. This is not obligatory.
cd /btrfs-admin/ btrfs subvolume create @data btrfs subvolume create @scan btrfs subvolume create @backups
Mount the subvolumes
Create one directory for each subvolume:
mkdir /mnt/nas/ mkdir /mnt/nas/data mkdir /mnt/nas/scan mkdir /mnt/nas/backups
Edit your /etc/fstab and add:
UUID=e8b50d90-0e20-45ec-a153-a725e074f306 /btrfs-admin/ btrfs noatime 0 0 UUID=e8b50d90-0e20-45ec-a153-a725e074f306 /mnt/nas/data btrfs subvol=@data,noatime 0 0 UUID=e8b50d90-0e20-45ec-a153-a725e074f306 /mnt/nas/scan btrfs subvol=@scan,noatime 0 0 UUID=e8b50d90-0e20-45ec-a153-a725e074f306 /mnt/nas/backups btrfs subvol=@backups,noatime 0 0
Explanations:
- we set pass=0 as fsck has no effect on btrfs
- replace the UUID with the one provided when formatting the partition
btrfsmaintenance
Note: Trixie will ship with btrfsd, which sends an email to the admin when a btrfs partition has errors. When Trixie is stable, this page will be updated in favor of btrfsd.
You only need to run scrub on a regular basis.
Edit /etc/default/btrfsmaintenance and replace BTRFS_SCRUB_MOUNTPOINTS="/" with BTRFS_SCRUB_MOUNTPOINTS="/btrfs-admin/"
run systemctl enable btrfs-scrub.timer
Get an Email when the partition has errors
TODO - wait for Debian Trixie
Samba
Packages
apt install samba
Users
Each samba user needs a linux user: ` useradd -M -s /usr/sbin/nologin -g sambashare parents useradd -M -s /usr/sbin/nologin -g sambashare kid useradd -M -s /usr/sbin/nologin -g sambashare printer `
useradd is the low level utility. If you want to create an user with system access, use adduser
-M : Do not create a home directory
-s /usr/sbin/nologin: do not allow login (use the shell nologin)
-g sambashare: all samba user belong to the group sambashare, so they can exchange data over samba
- We do not provide a password, so the user gets an exclamation mark in its /etc/shadow and is locked.
Then create samba users:
smbpasswd -a parents smbpasswd -a kid smbpasswd -a printer
-a adds the user
Use pdbedit -L to list the samba users
Directory permission rights
To share between the users within samba, we attribute all files and directories to the group "sambashare", and make sure that the group gets read+write rights on each file. Be careful: when creating a file outside samba (linux shell), make you attribute the files and directories to sambashare and give them read and write permission. We need to set the initial permissions to our nas shares:
chgrp -R sambashare /mnt/nas/* chmod -R ug+rwX,o= /mnt/nas/*
-R: recursive, not needed here as our share are empty
ug+rwX,o=: set files to rw, directories to rwx for user and group. Remove rights for other users.
Configuration
Adapt this sample configuration to your needs in /etc/samba/smb.conf. The global parameters should be static, you have to adapt the share below to set the path to the share and which users are allowed to access it.
[global]
server role = standalone server
# Description of the server
server string = My Home NAS
# We want Samba to log to /var/log/samba/log.{smbd,nmbd}
# To send to syslog also, use "logging = file, syslog@1"
logging = file
# Do something sensible when Samba crashes: mail the admin a backtrace
panic action = /usr/share/samba/panic-action %d
# Shared options in shares
force group = sambashare
# user & group always get rw for files (minimal rights)
force create mode = 0660
# Set maximal rights to the same as the create rights
create mask = 0660
# user & group always get rwx for directories + Set-GID bit
force directory mode = 2770
# Set maximal rights to the same as the create rights
directory mask = 2700
read only = no
# NAS Directories
[data]
path = /mnt/nas/data
valid users = parents
[scan]
path = /mnt/nas/scan
valid users = parents kid printer
[tmp]
path = /mnt/nas/tmp
valid users = parents kidThen reload samba with systemctl restart smbd
Btrfs Support
Samba in Debian supports "Btrfs Enhanced Server-Side Copy Offload".
RobertCheramy: configuration to activate this needed
Maintenance tasks
btrfs
Scrub
Defragmentation
You don't need to (and shouldn't) defragment your whole disk on a regular basis. You can find and fix defragmentation on individual files if you experience performance problems.
Replace a failed disk (Raid 1)
Notes:
- It is a good practice to try this procedure yourself with a virtual machine.
- the replacement disk must be clean and contain an empty partition of the same size of the old one. If you use an old disk, wipe the partition table with "parted /dev/vdd mklabel gpt" and create a new partition. Run wipefs -a on the partition to remove remaining btrfs-data.
parted /dev/vdd mklabel gpt # create the partition vdd1 cfdisk /dev/vdd # make sure no btrfs-data is stored wipefs -a /dev/vdd1
You can check the health of your disks with
root@ulm:/mnt/nas/backups/etc1# btrfs filesystem show /btrfs-admin/
Label: 'btrfs-data' uuid: e8b50d90-0e20-45ec-a153-a725e074f306
Total devices 2 FS bytes used 7.56MiB
devid 1 size 498.00MiB used 121.75MiB path /dev/sda1
devid 2 size 498.00MiB used 121.75MiB path /dev/sdb1If one of your disks fail, you will see something like:
root@ulm:/mnt/nas/backups/etc1# btrfs filesystem show /btrfs-admin/
Label: 'btrfs-data' uuid: e8b50d90-0e20-45ec-a153-a725e074f306
Total devices 2 FS bytes used 7.56MiB
devid 1 size 498.00MiB used 121.75MiB path /dev/sda1
devid 2 size 0 used 0 path /dev/sdb1 MISSINGAt this point, it depends on your system: - if you have hotswap an enough bays, insert a (blank) new drive - if you have hotswap but only two bays, replace the defect drive with a (blank) new one - if you don't have hotswap, shut down your NAS, replace the disk, and boot. The mount will fail and you will land in emergency mode, but you can boot from a Debian live USB-Stick to have some more comfort.
If you had to reboot, you must mount /btrfs-admin with the "degraded" option:
mount -o degraded /btrfs-admin
btrfs filesystem show /btrfs-admin
Label: 'btrfs-data' uuid: e8b50d90-0e20-45ec-a153-a725e074f306
Total devices 2 FS bytes used 7.56MiB
devid 1 size 498.00MiB used 121.75MiB path /dev/sda1
devid 2 size 0 used 0 path MISSING
btrfs replace start -B 2 /dev/sdb1 /btrfs-adminNotes:
-B is for no background mode
- if btrfs complains that there is an existing filesystem, wipe the metadata (see above)
root@ulm:~# btrfs replace start 2 /dev/vdd1 /btrfs-admin/ ERROR: /dev/vdd1 appears to contain an existing filesystem (btrfs) ERROR: use the -f option to force overwrite of /dev/vdd1
When replace is finished, and you were in emergency mode, you can reboot the system with systemctl reboot .
The disks are not synced yet, all the data that has been written while one disk was failed is only present on one disk.
root@ulm:~# btrfs device usage /btrfs-admin/ /dev/sda1, ID: 1 Device size: 498.00MiB Device slack: 0.00B Data,single: 64.00MiB Data,RAID1: 64.00MiB Metadata,single: 64.00MiB Metadata,RAID1: 49.75MiB System,single: 32.00MiB System,RAID1: 8.00MiB Unallocated: 216.25MiB /dev/sdb1, ID: 2 Device size: 498.00MiB Device slack: 0.00B Data,RAID1: 64.00MiB Metadata,RAID1: 49.75MiB System,RAID1: 8.00MiB Unallocated: 376.25MiB WARNING: Multiple block group profiles detected, see 'man btrfs(5)' WARNING: Data: single, raid1 WARNING: Metadata: single, raid1 WARNING: System: single, raid1
To solve this, run btrfs balance:
root@ulm:~# btrfs balance start -dconvert=raid1,soft -mconvert=raid1,soft /btrfs-admin/ Done, had to relocate 3 out of 6 chunks root@ulm:~# btrfs device usage /btrfs-admin/ /dev/sda1, ID: 1 Device size: 498.00MiB Device slack: 0.00B Data,RAID1: 64.00MiB Metadata,RAID1: 64.00MiB System,RAID1: 32.00MiB Unallocated: 338.00MiB /dev/sdb1, ID: 2 Device size: 498.00MiB Device slack: 0.00B Data,RAID1: 64.00MiB Metadata,RAID1: 64.00MiB System,RAID1: 32.00MiB Unallocated: 338.00MiB
Notes: * -dconvert=raid1,soft -mconvert=raid1,soft only balance (meda)data not saved as raid1 ("single" chunks)
To be sure that everything is now OK, run btrfs scrub :
root@ulm:~# btrfs scrub start /btrfs-admin/ scrub started on /btrfs-admin/, fsid e8b50d90-0e20-45ec-a153-a725e074f306 (pid=689) root@ulm:~# btrfs scrub status /btrfs-admin/ UUID: e8b50d90-0e20-45ec-a153-a725e074f306 Scrub started: Sun Jul 20 20:38:26 2025 Status: finished Duration: 0:00:00 Total to scrub: 29.95MiB Rate: 0.00B/s Error summary: no errors found root@ulm:~#
Congratulations! You're restored the redundancy!
