When a Btrfs filesystem is too fragile to hand over directly, btrfs-image captures its metadata into a file a developer can safely inspect. This guide covers dumping metadata to an image file, checking the result without treating it as a backup, and restoring to a disposable file when a damaged filesystem needs investigation. It uses btrfs-image from btrfs-progs 6.6.3, installed on Ubuntu as package version 6.6.3-1.1build2.
Start with the read-only help output. This also avoids assuming a newer online manual exactly matches the binary on your host.
$ command -v btrfs-image
/usr/bin/btrfs-image
$ dpkg-query -W -f='${Package} ${Version}\n' btrfs-progs
btrfs-progs 6.6.3-1.1build2
$ btrfs-image --help
usage: btrfs-image [options] source target
The installed help lists the short options -r, -c, -t, -o, -s, -w, -m and -d. The local btrfs-image(8) manpage documents the first seven, but not -d: that option is present in this installed 6.6.3 executable and means the dump also includes data. It conflicts with -w. Prefer the documented metadata-only mode unless a debugger explicitly needs file data.
Checkpoint: if the package version or help output differs, stop and read the matching local manual before copying the examples below.
In dump mode, the first argument is the btrfs device or file and the second is the output image. Use a clear, absolute destination outside the filesystem being read.
SOURCE_DEVICE='/dev/REPLACE_WITH_BTRFS_DEVICE'
IMAGE_FILE='/var/tmp/REPLACE_WITH_CASE_NAME.btrfs-image'
sudo btrfs-image "$SOURCE_DEVICE" "$IMAGE_FILE"
Replace both placeholders before running the command. A path such as /dev/nvme0n1p2 must be the btrfs filesystem you intend to capture, not merely a disk that happens to contain one. Check the identity first.
$ lsblk -f
$ findmnt -t btrfs
Do not write the image into the source filesystem if that filesystem is short of space or unstable. If the source is mounted and actively changing, the captured metadata may describe different points in time. For a reproducible debugging capture, arrange a maintenance window or use an appropriate read-only source copy.
Run the plain two-argument form for the normal case.
$ sudo btrfs-image "$SOURCE_DEVICE" "$IMAGE_FILE"
$ printf 'image status: %s\n' "$?"
image status: 0
$ stat -c 'image: %n, bytes: %s' "$IMAGE_FILE"
image: /var/tmp/REPLACE_WITH_CASE_NAME.btrfs-image, bytes: 123456
The byte count is host-specific. A zero exit status means the command reported no error. This is a metadata image for debugging, not a restorable backup of user files: normal output has file data zeroed while metadata and related structures are retained. Protect it as case material anyway, because names and metadata can still disclose information.
Warning: if the image path already exists, pause before replacing it. The command's output target is state-changing, and an existing investigation image may be the only copy. Choose a new filename or make a separately verified copy first: there is no undo command for an overwritten image file.
Use -c to select a compression level from 0 to 9 and -t to select 1 to 32 processing threads.
$ sudo btrfs-image -c 6 -t 4 "$SOURCE_DEVICE" "$IMAGE_FILE"
$ printf 'image status: %s\n' "$?"
image status: 0
-w only when the extent tree is corrupted and you need btrfs-image to walk all trees manually for referenced blocks. It is a recovery diagnostic, not a general quality improvement.-d sparingly: it also dumps data, conflicts with -w, and makes the result larger and less suitable for sharing.-s casually. It sanitises file names, changes directory-hash relationships, and can mask problems. A single -s uses garbage names; two attempt hash collisions and can be very CPU-intensive.Keep the command line in the case notes so another operator can reproduce the capture.
Restore mode reverses the argument roles: the image is the source and the btrfs device or file is the target. Create a separate target file and never substitute a live disk path while experimenting.
RESTORE_TARGET='/var/tmp/REPLACE_WITH_DISPOSABLE_TARGET.img'
truncate -s 4G "$RESTORE_TARGET"
sudo btrfs-image -r "$IMAGE_FILE" "$RESTORE_TARGET"
printf 'restore status: %s\n' "$?"
ls -lh "$RESTORE_TARGET"
The target size must suit the image and its filesystem layout. The command may modify it even when a later mount or check fails, so treat the target as disposable until you have verified the result. If you need to abandon it, unmount it first if it was mounted, then remove that explicitly named test file.
$ sudo umount /mnt/REPLACE_WITH_TEST_MOUNT 2>/dev/null || true
$ rm -f -- "$RESTORE_TARGET"
Destructive action: that removal is irreversible. Confirm the variable contains only the intended temporary target before running it; never pair an unset or broadly constructed path with a destructive command.
With -r, the current restore method fixes the superblock chunk tree by using one stripe pointing at the primary device. This lets a restored filesystem be mounted, or its tree log replayed, when the metadata permits it. A successful restore still does not prove the filesystem is healthy.
-o selects the old restore method and does not fix up the chunk tree. The local manual warns that the resulting filesystem cannot be mounted; use it only when a specific investigation requires the old layout behaviour.
$ sudo btrfs-image -r -o "$IMAGE_FILE" "$RESTORE_TARGET"
$ printf 'old-method restore status: %s\n' "$?"
old-method restore status: 0
Do not combine this example with a target you expect to mount. If a restore status is non-zero, retain the diagnostic output and work from a new target rather than repeatedly overwriting the same test file.
For a filesystem that uses more than one device, -m enables multi-device restore and more than one target device must be provided. Do not infer the device list from a single mount path: record the original device mapping and prepare replacement targets of the correct size before attempting recovery. A multi-device restore is a destructive storage operation and belongs in a maintenance window with a tested rollback plan.
For an ordinary single-device debugging image, leave -m out. If you are unsure whether the source is multi-device, inspect it before writing anything.
$ sudo btrfs filesystem show "$SOURCE_DEVICE"
$ sudo btrfs filesystem usage "$SOURCE_DEVICE"
lsblk or findmnt.-o separate from the normal restore method.