Btrfs/Getting Started

From Forza's ramblings

Getting Started with Btrfs[edit | edit source]

A disassembled Hard Disk.

Hi there,

If you are new to Btrfs this guide will help you set up a basic Btrfs filesystem. You can then further read up on the more advanced topics such as snapshots, backups, compression and volume management.

Before continuing you may want to read a summary of the many unique Btrfs features.

Preparing your disks[edit | edit source]

Although Btrfs allows the use of raw disks, but it is recommended that you create a partition table and at least one partition so that other filesystems or tools do not mistake the disk. I recommend you use a GUID Partition Tables (GPT) instead of the legacy old MBR/DOS type. GNU Parted is available on most systems, but cfdisk, fdisk and other tools can do the job just as well too.

Single or multi-disk filesystem[edit | edit source]

This is the easiest set up. You bought one or two new disks and want to run Btrfs on them:

Partitioning[edit | edit source]

First, setup a partition table on your disks using GNU Parted. Make sure you start the partion on the 4MiB boundary to ensure alignment with the hardware block size.

Partition Filesystem Start End Partition type
/dev/sdb1 Btrfs 4MiB 100% Linux filesystem
/dev/sdc1 Btrfs 4MiB 100% Linux filesystem

Invoke parted with the disk you want to edit: # parted /dev/sdb

GNU Parted 3.2
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted)

First check there is no existing partitions or partition tables on the disk:

(parted) unit MiB    # This changes the displayed unit to MiB (Megabytes)
(parted) print
Error: /dev/sdb: unrecognised disk label
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sdb: 102400MiB
Sector size (logical/physical): 512B/512B
Partition Table: unknown
Disk Flags:

Create a GPT partition table:

(parted) mklabel gpt

Now create a partition:

(parted) mkpart my-btrfs btrfs 4MiB 100%

You can list the resulting layout using print command:

(parted) print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sdb: 51200MiB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start    End       Size      File system  Name      Flags
 1      4.00MiB  51199MiB  51195MiB               my-btrfs


Formatting[edit | edit source]

The basic formatting command is mkfs.btrfs -L <label> --data <profile> <device_1> <device_2> <device_n>. Btrfs support several different profiles. Read more about profiles and Volume management on the Btrfs/Features page.

This will create a standard btrfs filesystem spanning both disks and give it the name my-data. The filesystem will have the total sum of both disks, in this case 150GiB.

# mkfs.btrfs -L my-data --data single /dev/sdb1 /dev/sdc1
btrfs-progs v4.19.1
See http://btrfs.wiki.kernel.org for more information.

Label:              my-data
UUID:               a36f20ff-f0b1-466d-a7dc-355c189b3e39
Node size:          16384
Sector size:        4096
Filesystem size:    149.99GiB
Block group profiles:
  Data:             single            8.00MiB
  Metadata:         RAID1             1.00GiB
  System:           RAID1             8.00MiB
SSD detected:       yes
Incompat features:  extref, skinny-metadata
Number of devices:  2
Devices:
   ID        SIZE  PATH
    1    50.00GiB  /dev/sdb1
    2   100.00GiB  /dev/sdc1

If you rather want to use RAID1 (mirroring) you would do:

# mkfs.btrfs -L my-data --data RAID1 /dev/sdb1 /dev/sdc1

Btrfs supports combining disks of different sizes. Use the excellent disk space calculator at https://carfax.org.uk/btrfs-usage/ to see how you best can combine your disks.

Btrfs as root filesystem[edit | edit source]

This is a common way to set up a single disk root filesystem. a Separate boot partition so that we can use EFI or use new advanced Btrfs features on the root filesystem without causing issues with the boot loader. Although Btrfs supports swap files in recent kernels, there are still some limitations, so we choose to create a swap partition instead.

Follow the parted guide from Btrfs/Getting_Started#Preparing_your_disks

Partition Filesystem Start End Partition type
/dev/sda1 (bootloader) 0 4MiB BIOS boot partition
/dev/sda2 Btrfs/FAT32* 4MiB 1GiB EFI system partition
/dev/sda3 Swap 1GiB 4GiB Swap partition
/dev/sda4 Btrfs 4GiB 100% Linux filesystem
1) Note that if you use EFI you need a FAT32 formatted EFI System Partition.
2) If you have a very old GRUB, then it may not support Btrfs for /boot (/dev/sda2). In that case use Ext4

When deciding on swap space you should estimate the needed size based on RAM and if you are going to use Hibernation. There is a good guide over at Ubuntu that explains why you need swap and how much.

 RAM   No hibernation    With Hibernation  Maximum
 1GB              1GB                 2GB      2GB
 2GB              1GB                 3GB      4GB
 3GB              2GB                 5GB      6GB
 4GB              2GB                 6GB      8GB
 5GB              2GB                 7GB     10GB
 6GB              2GB                 8GB     12GB
 8GB              3GB                11GB     16GB
12GB              3GB                15GB     24GB
16GB              4GB                20GB     32GB
24GB              5GB                29GB     48GB
32GB              6GB                38GB     64GB
64GB              8GB                72GB    128GB

Subvolumes[edit | edit source]

Btrfs subvolumes is one of the unique features of Btrfs. A subvolume is a part of the filesystem but has its own independent file/directory hierarchy.

Subvolumes is a great way to separate your data in logical sections. They share all the space for the filesystem, but can be mounted separately, be snapshotted and sent for backups. In most ways, a subvolume looks like a normal directory. You can copy it, write in it, rename it, etc. Subvolumes can also be nested.

When you do mkfs.btrfs /dev/sdb1 btrfs automatically creates a default subvolume. This will be the default subvolume when mounting the filesystem with no options.

I usually make two directories, volume and snapshot in which I create all default subvolumes. This makes it easy to separate your snapshots from your normal subvolumes. Try not to create nested subvolumes as it makes it more complicated to manage.

toplevel            (default subvolume root directory)
+-- dir_1           (normal directory)
|   +-- file_2      (normal file)
|   \-- file_3      (normal file)
\-- volume          (directory)
    +-- root        (subvolume)
    |   \-- file_4  (normal file)
    +-- home        (subvolume)
    +-- tmp         (subvolume)
    \-- file_5      (normal file)
\-- snapshot        (directory)

Use the -o subvol= mount option to specify what subvolume root to mount.

# mount /dev/sdb1 /home    -o subvol=volume/home # mounts the home subvolume in /home
# mount /dev/sdb1 /var/tmp -o subvol=volume/tmp  # mounts the tmp  subvolume in /var/tmp

Many distributions have lots of subvolumes predefined. It's usually not necessary and is often a legacy from older times when we were used to having separate partitions. With Btrfs you can add and remove subvolumes at any time. If unsure, start with few subvolumes, and expand later if you need to.

Example of a mounted root filesystem layout:

Path Description
/ The root subvolume
/home This where users' home directories are
/root This is where root's home directory is

/etc/fstab: It is usually best to use UUID= instead of /dev/sda in fstab. The command blkid gives you a list of devices and filesystems's UUID.

# blkid
/dev/sda2: LABEL="btrfs-boot" UUID="1128e72e-b00f-4c2a-a1e1-afa89f3c11cc" UUID_SUB="43e7d65d-835a-40d5-a204-c84882532db5" BLOCK_SIZE="4096" TYPE="btrfs" PARTUUID="817e8dfa-28bb-40cc-9289-da9f77ad6c91"
/dev/sda3: LABEL="btrfs-root" UUID="446d32cb-a6da-45f0-9246-1483ad3420e0" UUID_SUB="a286a010-6db4-4f79-aa2c-a3b449b40e67" BLOCK_SIZE="4096" TYPE="btrfs" PARTLABEL="btrfs-root" PARTUUID="7e2b7b21-625c-4908-8b0e-b827254000e5"
/dev/sda4: LABEL="swap"       UUID="a386e543-8698-4422-8a57-53ea545b356e" TYPE="swap" PARTLABEL="swap" PARTUUID="fb3fd442-1654-4587-8580-fd3644c3f9f3"
# /etc/fstab
UUID=a386e543-8698-4422-8a57-53ea545b356e   none          swap    sw,pri=0                                        0 0
UUID=446d32cb-a6da-45f0-9246-1483ad3420e0   /             btrfs   noatime,space_cache=v2,subvol=volume/root       0 0
UUID=446d32cb-a6da-45f0-9246-1483ad3420e0   /home         btrfs   noatime,space_cache=v2,subvol=volume/home       0 0
UUID=446d32cb-a6da-45f0-9246-1483ad3420e0   /root         btrfs   noatime,space_cache=v2,subvol=volume/home_root  0 0
UUID=446d32cb-a6da-45f0-9246-1483ad3420e0   /var/tmp      btrfs   noatime,space_cache=v2,subvol=volume/var_tmp    0 0
UUID=446d32cb-a6da-45f0-9246-1483ad3420e0   /mnt/rootvol  btrfs   noatime,space_cache=v2,subvol=/                 0 0

Take a note of the last line. This is your top-level subvolume. In here you can access all subvolumes, snapshot them, and do maintenance tasks.

# ls -l /mnt/rootvol/
drwxr-xr-x 1 root root 6224 Aug  2 13:01 snapshots/
drwxr-xr-x 1 root root  190 Apr 30 22:28 volume/
# ls -l /mnt/rootvol/volume
drwxr-xr-x 1 root   root     36 Jul 30 22:27 home/
drwxr-xr-x 1 root   root    484 Aug  2 14:04 home_root/
drwxr-xr-x 1 root   root    306 Jul 23 12:22 root/
drwxrwxrwx 1 root   root     96 Aug  2 11:43 var_tmp/
# ls -l /mnt/rootvol/snapshot
drwxr-xr-x 1 root   root     36 Jul 30 22:27 home.20200730T2301/
drwxr-xr-x 1 root   root     36 Jul 30 22:27 home.20200731T0001/
drwxr-xr-x 1 root   root     36 Jul 30 22:27 home.20200801T2201/
drwxr-xr-x 1 root   root    306 Jul 23 12:22 root.20200730T0001/
drwxr-xr-x 1 root   root    306 Jul 23 12:22 root.20200731T0001/
drwxr-xr-x 1 root   root    306 Jul 23 12:22 root.20200802T1401/

For an extensive guide how to manage subvolumes, there is a SysAdminGuide over at kernel.org's btrfs wiki.

GRUB / Boot loader[edit | edit source]

Further Reading[edit | edit source]