scripts-fabq/notes/btrfs.md
Fabrice Quenneville 89e4bd519a docs(notes): expand storage, btrfs, linux, and ssh notes
btrfs.md:
- Add device scan (no-arg form) and device stats --reset / -z
- Add read-only mount, remount with performance/default options
- Add Degraded Mount and Missing Device Removal subsection
- Add stdbuf + zstd backgrounded defrag with log output
- Add RAID1 balance conversion
- Add ionice for scrub, watch scrub+device stats, watch scrub+temperatures
- Add Recovery → Filesystem Check (btrfs check, --force)
- Add Recovery → Diagnosis (journal by date, dmesg btrfs filter)

linux.md:
- Add CPU info commands (lscpu, /proc/cpuinfo, core count)
- Add GPU info (lspci | grep vga) and CPU scaling driver
- Add mount --bind and chroot with pseudo-fs setup
- Add update-initramfs -k all and -c -k $(uname -r) variants
- Add NFS section (showmount, exportfs)
- Add Network Diagnostics section (curl timing, high-freq ping, jumbo frame ping)
- Add journal date filtering and microcode grep to Diagnosis

ssh.md:
- Add Placeholders section
- Replace all hardcoded usernames, hostnames, IPs, and key paths with placeholders
- Add Skip Host Key Verification section (StrictHostKeyChecking, UserKnownHostsFile)

storage.md:
- Add lsblk -e 7 to exclude loop devices
- Add blkid <partition> variant
- Add cat /proc/mounts grep
- Add SMART filtered greps (Reallocated, Pending, UDMA_CRC, Load_Cycle_Count)
- Add drive temperature one-liner and watch loop
- Add Hardware Monitoring section (lm-sensors, sensors-detect, sensors)
- Add Kernel Messages section (dmesg tail, err/warn, -T, nvme, ata/scsi, I/O, ATA port mapping)
- Add strings on raw device to Hex Dump
2026-05-12 01:03:26 -04:00

14 KiB

BTRFS

Table of Contents

Placeholders

Replace the placeholders below with the appropriate values for your setup:

  • Devices

    • Block device: <device> (e.g., /dev/sda)
    • Source device to replace: <source-device> (e.g., /dev/sdb)
    • Target device: <target-device> (e.g., /dev/sdc)
    • UUID: <uuid> (e.g., a1b2c3d4-e5f6-7890-abcd-ef1234567890)
  • Paths

    • Mount point: <mountpoint> (e.g., /mnt/media)
    • Subvolume name: <subvolume> (e.g., root, home, backups, snapshots)
    • Subvolume ID: <subvolume-id> (e.g., 257)
    • Snapshot label: <snapshot-label> (e.g., 2024-09-15)

BTRFS Command Shorthands

Most btrfs subcommands accept shortened aliases. The table below lists the common ones used throughout this document.

Long form Short form
btrfs filesystem btrfs fi
btrfs filesystem show btrfs fi show
btrfs filesystem usage btrfs fi usage
btrfs filesystem df btrfs fi df
btrfs filesystem resize btrfs fi resize
btrfs filesystem defragment btrfs fi defrag
btrfs subvolume btrfs sub
btrfs subvolume list btrfs sub list
btrfs subvolume snapshot btrfs sub snap
btrfs subvolume delete btrfs sub del
btrfs subvolume get-default btrfs sub get-default
btrfs subvolume set-default btrfs sub set-default
btrfs device btrfs dev
btrfs device add btrfs dev add
btrfs device usage btrfs dev usage
btrfs device stats btrfs dev stats
btrfs balance start btrfs bal start
btrfs balance status btrfs bal status
btrfs balance cancel btrfs bal cancel
btrfs inspect-internal btrfs insp

Information on Filesystem

Show Basic Filesystem Information

Display basic information (size, IDs, paths, etc.) for the specified mountpoint:

btrfs fi show <mountpoint>

Display detailed usage information

To show detailed usage information (allocated, unallocated, free, used, etc.) for the specified mountpoint:

btrfs fi usage <mountpoint>

Display detailed usage information as a table

btrfs fi usage -T <mountpoint>
  • -T The tabular flag gives you a nice grid that shows exactly how much Data, Metadata, and System space is allocated per device.

Display Detailed Allocation Information

View block groups and used space:

btrfs fi df <mountpoint>

Get Detailed Device Usage Statistics

Physical size, unallocated space, RAID levels, etc.:

btrfs device usage <mountpoint>

Scan and Display BTRFS Information

Scan all devices or a specific drive:

btrfs device scan
btrfs device scan <device>

Retrieve Statistics and Error Information

Read errors, write errors, flush errors, etc.:

btrfs device stats <mountpoint>

Reset Device Error Counters

Reset all per-device error counters to zero after acknowledging them:

btrfs device stats --reset <mountpoint>
btrfs device stats -z <mountpoint>
  • -z / --reset: Zeroes the counters after printing. Useful after a known event you've already investigated.

List BTRFS Subvolumes

btrfs subvolume list <mountpoint>

Default Subvolume

Check if a non-standard subvolume is set as the default:

btrfs subvol get-default <mountpoint>
btrfs subvol list <mountpoint>

Change the default subvolume:

btrfs subvol set-default <subvolume-id> <mountpoint>

Verify Current Cache Version

Check if your filesystem is using cache V1 by device:

btrfs inspect-internal dump-super -f <device> | grep cache_generation

By UUID:

btrfs inspect-internal dump-super -f $(blkid -U <uuid>) | grep cache_generation
  • If cache_generation is present, cache V1 is in use. If absent, the filesystem is already using V2.

Drive Manipulation

Mount Whole Drive

mount UUID=<uuid> <mountpoint>

Mount Subvolume by Name

mount UUID=<uuid> -o subvol=<subvolume> <mountpoint>

Mount Subvolume by ID

btrfs subvol list /
mount -o subvolid=<subvolume-id> /dev/disk/by-uuid/<uuid> <mountpoint>

Mount Read-Only

Mount a partition in read-only mode, useful for forensics or recovery without risking further writes:

mount -r <device> <mountpoint>

Remount with Performance Options

Apply common performance mount options to a live filesystem without unmounting:

mount -o remount,noatime,compress=zstd:3,autodefrag,space_cache=v2 <mountpoint>

Remount with Default Options

mount -o remount,defaults,noatime,compress=zstd:3 <mountpoint>

Add a New Drive

btrfs device add <device> <mountpoint>

Resize Filesystem

Grow the filesystem on a specific device to its maximum:

btrfs filesystem resize 1:max <mountpoint>

Create Subvolumes

btrfs subvol create <mountpoint>/<subvolume>

Replace Drives

Start the replacement process:

Copies data from the old drive to the new drive while the filesystem remains mounted:

btrfs replace start <source-device> <target-device> <mountpoint>
  • <source-device>: Drive to be replaced.
  • <target-device>: Drive to replace it with.
  • <mountpoint>: Mount point of the BTRFS filesystem.

Monitor the progress:

btrfs replace status <mountpoint>

Monitor progress interactively:

btrfs replace status -i <mountpoint>
  • -i: Updates progress in real time.

Notes:

  • btrfs replace works on a live mounted filesystem — no unmounting required.
  • Useful for both failing drive replacement and capacity upgrades.
  • Ensure the target drive has enough space to accommodate the source data.

Degraded Mount and Missing Device Removal

Use when a drive has failed and you need to access the filesystem with the remaining devices.

Mount in degraded mode:

mount -o ro,degraded <device> <mountpoint>

Mount a specific subvolume in degraded mode:

mount -t btrfs -o degraded,subvol=<subvolume>,noatime,compress=zstd:3 UUID=<uuid> <mountpoint>

Remove the missing device from the filesystem:

Once mounted degraded, remove the placeholder for the missing drive:

btrfs device remove missing <mountpoint>
  • This cleans up the missing device slot so the filesystem no longer expects it.
  • Only safe to run if data is intact on the remaining devices (e.g., RAID1 with one drive).

Filesystem Manipulation

Upgrading Btrfs Block Group Cache to V2

Non-root filesystems (running system):

mount -o remount,clear_cache,space_cache=v2 <mountpoint>

Root filesystem (running system):

  1. Check if using cache V1:

    btrfs inspect-internal dump-super -f <device> | grep cache_generation
    
  2. Enable cache V2 via GRUB:

    nano /etc/default/grub
    # Add to GRUB_CMDLINE_LINUX_DEFAULT or GRUB_CMDLINE_LINUX:
    # rootflags=clear_cache,space_cache=v2
    

    Example:

    GRUB_CMDLINE_LINUX_DEFAULT="quiet splash rootflags=clear_cache,space_cache=v2"
    
    update-grub
    reboot
    
  3. Verify the change:

    btrfs inspect-internal dump-super -f <device> | grep cache_generation
    
  4. Remove clear_cache from GRUB after confirming:

    nano /etc/default/grub
    # Remove clear_cache from rootflags, then:
    update-grub
    

From a live system:

apt update
apt install btrfs-progs
lsblk -o NAME,UUID
blkid
mount -o clear_cache,space_cache=v2 /dev/disk/by-uuid/<uuid> <mountpoint>
btrfs inspect-internal dump-super -f /dev/disk/by-uuid/<uuid> | grep cache_generation
umount <mountpoint>

Defrag

Standard recursive defrag with LZO compression:

btrfs filesystem defrag -r -v -clzo <mountpoint>
  • -r: Recursive.
  • -v: Verbose.
  • -clzo: Optional LZO compression to save space.

Recursive defrag with Zstd compression, logged to file:

Runs in the background with unbuffered output so the log file updates in real time:

stdbuf -oL btrfs filesystem defrag -r -v -czstd <mountpoint> > /root/<date>-defrag.log 2>&1 &
  • stdbuf -oL: Forces line-buffered stdout so log entries appear immediately.
  • -czstd: Zstd compression (better ratio than LZO, available since kernel 5.1).
  • &: Runs in the background; use tail -f /root/<date>-defrag.log to monitor.

Balances

Full balance on nearly empty block groups:

btrfs balance start --full-balance -dusage=0 -musage=0 <mountpoint>
  • --full-balance: Default but with a warning if not specified.
  • -dusage=0: Only balance data block groups that are ~0% full.
  • -musage=0: Only balance metadata block groups that are ~0% full.

Full balance on partially used block groups:

btrfs balance start --full-balance -dusage=50 -musage=50 <mountpoint>
  • -dusage=50: Include data block groups less than 50% full.
  • -musage=50: Include metadata block groups less than 50% full.

Balance data in the background:

btrfs balance start --bg -d <mountpoint>

Balance metadata in the background:

btrfs balance start --bg -m <mountpoint>

Balance data and metadata in the background:

btrfs balance start --bg --full-balance -dusage=0 -musage=0 <mountpoint>

Balance a limited number of chunks:

btrfs balance start --bg -dlimit=100 <mountpoint>

Convert to RAID1:

Rebalances data and metadata to RAID1 profile. Use after adding a second drive or to switch from single to mirrored:

btrfs balance start -mconvert=raid1 -dconvert=raid1 <mountpoint>

Cancel a balance:

btrfs balance cancel <mountpoint>

Monitor balance status:

btrfs balance status <mountpoint>

Scrub

Start a scrub

The scrub operation verifies data integrity against checksums:

btrfs scrub start <mountpoint>

Check scrub status:

btrfs scrub status <mountpoint>

Cancel a scrub:

btrfs scrub cancel <mountpoint>

Lower scrub I/O priority:

Reduce the impact of a running scrub on system I/O by setting it to idle class:

ionice -c 3 -p $(pgrep btrfs-scrub)
  • -c 3: Idle class — only uses I/O when no other process needs it.

Watch scrub status and device stats:

Continuously display scrub progress and per-device error counters:

watch -n 10 "btrfs scrub status <mountpoint>; echo ''; btrfs device stats <mountpoint>"

Watch scrub status and all drive temperatures:

watch -n 5 "btrfs scrub status <mountpoint> && echo '' && \
smartctl --scan | awk '{print \$1}' | while read dev; do \
  echo -n \"\$dev: \"; \
  smartctl -A \$dev | grep -iE 'Temperature|Airflow_Temp' | awk '\
    /Temperature_Celsius/ {print \$10 \"°C\"} \
    /Airflow_Temperature_Cel/ {print \$10 \"°C\"} \
    /Temperature:/ {print \$2 \"°C\"}' | head -n 1; \
done && echo '' && btrfs device stats <mountpoint>"

Snapshots

Create Snapshots

  1. Mount the snapshots subvolume:

    mount UUID=<uuid> -o subvol=snapshots <mountpoint>
    
  2. Create a snapshot:

    btrfs subvolume snapshot <source-subvolume> "<mountpoint>/<snapshot-label>"
    
  3. Unmount after creating:

    umount <mountpoint>
    

Delete Snapshots

  1. Mount the snapshots subvolume:

    mount -o subvol=snapshots /dev/disk/by-uuid/<uuid> <mountpoint>
    
  2. List available snapshots:

    btrfs subvol list <mountpoint>
    
  3. Delete the desired snapshot:

    btrfs subvolume delete <mountpoint>/<snapshot-label>
    
  4. Unmount after deleting:

    umount <mountpoint>
    

Backup Procedures

Snapshot backup procedure:

  1. Mount snapshot location:

    mount UUID=<uuid> -o subvol=snapshots <mountpoint>
    
  2. Create snapshots for the desired subvolumes:

    btrfs subvolume snapshot / "<mountpoint>/root/<snapshot-label>"
    btrfs subvolume snapshot /home "<mountpoint>/home/<snapshot-label>"
    btrfs subvolume snapshot <source-subvolume> "<mountpoint>/<subvolume>/<snapshot-label>"
    
  3. Unmount after creating snapshots:

    umount <mountpoint>
    

Recovery

  1. Mount a Subvolume with Recovery Options:

    mount -o recovery,subvol=<subvolume> UUID=<uuid> <mountpoint>
    
  2. Clear Cache During Mount:

    mount -o clear_cache,subvol=<subvolume> UUID=<uuid> <mountpoint>
    
  3. Data Restoration with btrfs restore:

    btrfs restore -D <device>
    

Filesystem Check

Run offline consistency checks on an unmounted BTRFS filesystem.

Check an unmounted filesystem:

btrfs check <device>
  • Must be run on an unmounted device. Running on a mounted filesystem risks corruption.
  • Use the UUID path if needed: /dev/disk/by-uuid/<uuid>

Force check (use with caution):

btrfs check --force <device>
  • --force: Bypasses the mount check. Only use this if you are certain the filesystem is not mounted and understand the risks.

Diagnosis

Filter system logs and kernel messages to diagnose BTRFS-related events.

Search journal logs by date range:

journalctl --since "<date>" --until "<date>" | grep -i btrfs

Example:

journalctl --since "2026-01-01" --until "2026-01-02" | grep -i btrfs

Search kernel ring buffer for BTRFS events:

dmesg | grep -i btrfs