BTRFS

Create FS

mkfs.btrfs --checksum xxhash -O no-holes -R free-space-tree -m dup ${DEVICE}
xxhash requires Linux 5.5.
free-space-tree (AKA space_cache=v2) is default since 5.15.
no_holes is default since 5.15.

Tip

no_holes enables better size-optimized representation for sparse files. Can be enabled after creation also:

btrfstune -n ${DEVICE}

Mount

Recommended mount options:

discard=async,relatime

Important BTRFS options:

discard=<value>

Issue discard/TRIM to inform underlying storage about freed space.

<value>:

sync

Issue discard immediately when space is freed.

async

Merge discard requests and submit them asynchronously for better performance.

discard without a value is equal to discard=sync.

relatime

Only update access time when modification is updated too. Note that CoW operations are issued when updating atime on files that have snapshots impacting performance and space requirements.

See also Atime and btrfs: a bad combination?.

space_cache=v2

Enable space cache v2 improving performance on large drives, in particular. Corresponds to -R free-space-tree option of mkfs.btrfs.

Compression

Enable compression on directory:

btrfs property set ${PATH} compression zstd

Newly created files within directory will be compressed (if content is compressible).

Existing files to be force-compressed using defrag:

btrfs filesystem defrag -r -c zstd ${PATH}

See also:

Disable Copy on Write (NOCOW)

Disable CoW:

setfattr +C ${PATH}

This is only applied to newly created files in directory with the NOCOW flag and empty files.

Warning

Enabling NOCOW disables checksumming and compression.

This is required to preserve performance for workloads that modify existing files heavily without rewriting the whole file. Databases and VM images are usually used this way.

See also:

Drive Errors

Error statistics:

$ btrfs device stats ${MOUNT_POINT}
[/dev/mapper/luks-bulk-main].write_io_errs    0
[/dev/mapper/luks-bulk-main].read_io_errs     0
[/dev/mapper/luks-bulk-main].flush_io_errs    0
[/dev/mapper/luks-bulk-main].corruption_errs  1
[/dev/mapper/luks-bulk-main].generation_errs  0

Tip

Use --check for the command to return with a non-zero code if any of the counters is non-zero.

Check for BTRFS warnings and BTRFS errors:

$ journalctl -k -g '^BTRFS (error|warning)'
Dec 22 13:23:43 mia kernel: BTRFS warning (device dm-15): csum failed root 19830 ino 2360 off 7357997056 csum 0x61debf728dffc131 expected csum 0xe1e94b36ab30f753 mirror 1
Dec 22 13:23:43 mia kernel: BTRFS error (device dm-15): bdev /dev/mapper/luks-bulk-main errs: wr 0, rd 0, flush 0, corrupt 1, gen 0