Home / Alt manpages / btrfs-inspect-internal(8)

  • btrfs-inspect-internal(8)
  • Admin command
  • linux

Query Btrfs Internals with inspect-internal

Reach for btrfs inspect-internal when you need one narrow answer about a Btrfs filesystem, not a full check. This guide uses the locally installed btrfs-progs 6.6.3 and takes about 10 minutes if you already have a Btrfs device or mount point to inspect.

Before you start

You need the btrfs command from the btrfs-progs package and a real Btrfs path or device. Commands that query mounted filesystem state or issue Btrfs ioctls generally need root privileges. Reading a superblock or tree from a device is diagnostic, but choose the device carefully: a typo can point you at the wrong filesystem, and large tree dumps can expose more information than you expected.

Replace the placeholders below. /mnt/data must be a Btrfs mount point, and /dev/mapper/data must be one of that filesystem's devices. Do not substitute a mounted filesystem's directory where the command expects <device>.

btrfs --version
findmnt -t btrfs
lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINTS

On this machine, the first command reports btrfs-progs v6.6.3. Available subcommands can vary with the package version, so checking the installed binary is worthwhile.

1. Identify a subvolume by path or ID

Start with rootid when a path is inside a mounted Btrfs filesystem: it prints the tree root ID of the containing subvolume, or the subvolume's own ID if the path itself is a subvolume. This is a read-only query and normally needs no elevated privileges.

btrfs inspect-internal rootid /mnt/data/projects
echo $?

A successful run prints a numeric ID, then an exit status of 0. An error such as not a btrfs filesystem means the path is not on Btrfs, the filesystem is not mounted as expected, or the command could not obtain the required information. The result is undefined for an empty subvolume, identified by inode number 2.

The inverse query is subvolid-resolve: it accepts a subvolume ID and a path on the relevant filesystem, then resolves the absolute path of that subvolume. Because it uses a privileged ioctl, run it with sudo.

sudo btrfs inspect-internal subvolid-resolve <SUBVOLUME_ID> /mnt/data

For example, if the previous command printed 256:

sudo btrfs inspect-internal subvolid-resolve 256 /mnt/data

Checkpoint

Do not treat an ID as globally meaningful. It belongs to one Btrfs filesystem, so supply a path on the filesystem you meant to query. A failure normally means the ID does not exist there, the path is not a suitable Btrfs path, or the command lacks privilege.

2. Inspect a superblock on a device

dump-super reads the textual superblock representation from one or more devices. It prints the first superblock copy by default and reports checksum status, device information and filesystem UUIDs, useful when a mount is failing or you need to confirm which filesystem a device belongs to.

sudo btrfs inspect-internal dump-super /dev/mapper/data | less
  • --all shows all present superblock copies.
  • --full adds the system chunk array and backup roots.
  • --super 0, --super 1 or --super 2 inspects a particular standard mirror. The older -i spelling is deprecated, and the meaning of -s changed in btrfs-progs 4.8, so scripts should use --super for a mirror or --bytenr for a non-standard byte offset.
sudo btrfs inspect-internal dump-super --all /dev/mapper/data
sudo btrfs inspect-internal dump-super --super 1 /dev/mapper/data
sudo btrfs inspect-internal dump-super --full /dev/mapper/data

Warning

--force is deliberately dangerous. It asks the program to print data even without a valid Btrfs signature, and the result can be entirely wrong. Use it only while investigating a known damaged or unusual image, record the exact device and offset, and never treat its output as proof a device contains a valid filesystem.

3. Dump selected internal trees

dump-tree exposes Btrfs tree structures from a device. It does not print file data, but it can contain file names, directory entries, subvolume names and extended attributes: treat the output as sensitive before sending it to anyone else. Add --hide-names when names are not needed, though lengths can still reveal information.

sudo btrfs inspect-internal dump-tree --hide-names --roots /dev/mapper/data
sudo btrfs inspect-internal dump-tree --device /dev/mapper/data
sudo btrfs inspect-internal dump-tree --extents /dev/mapper/data
  • The first command limits output to short root information.
  • --device selects device-related trees; --extents selects extent and device trees.
  • --uuid selects the UUID tree, which may be absent and produce no output; --backups selects root and backup-root information.

For a known block, add -b with its number; it may be repeated, and --follow includes child tree blocks. The default traversal is breadth-first in current versions, including 6.6.3, so use --bfs or --dfs explicitly in scripts whose output order matters.

sudo btrfs inspect-internal dump-tree --hide-names -b <BLOCK_NUMBER> /dev/mapper/data

Use --noscan when you want the command to use only the devices named on the command line: a useful boundary on multi-device systems, where automatic discovery of other devices could make a diagnostic dump larger or less reproducible.

4. Resolve files and check shrink limits

inode-resolve finds all paths to an inode within a subvolume, including hard links. logical-resolve works from a logical address in the filesystem's address space and can return paths to files at that address. Both need root privileges; the latter's -P option skips path resolving and prints inodes instead.

sudo btrfs inspect-internal inode-resolve <INODE> /mnt/data
sudo btrfs inspect-internal logical-resolve -P <LOGICAL_ADDRESS> /mnt/data

For logical lookups, -o finds references to an extent rather than one block and needs kernel support for the V2 ioctl, added in kernel 4.15. The filename buffer defaults to 64 KiB and can be changed with -s, up to 16 MiB; larger buffers also need that kernel support.

min-dev-size reports the smallest size to which a Btrfs device can shrink. It does not resize anything, but it is still a privileged query and should be run against the correct mounted filesystem.

sudo btrfs inspect-internal min-dev-size /mnt/data
sudo btrfs inspect-internal min-dev-size --id <DEVICE_ID> /mnt/data

The device ID defaults to 1. This command is a planning input, not permission to change a partition or filesystem. Do not act on a stale result after writes, device changes or a balance operation. The inspect command itself changes no filesystem state, so there is nothing to undo.

5. Inspect swapfile mappings and tree statistics

If a Btrfs swapfile is used for hibernation, map-swapfile checks its suitability and reports the device-specific physical offset. With --resume-offset, it prints only the value intended for /sys/power/resume_offset.

sudo btrfs inspect-internal map-swapfile /swapfile
sudo btrfs inspect-internal map-swapfile --resume-offset /swapfile

Do not replace this with filefrag or FIEMAP physical values: Btrfs maps its internal addresses differently for this purpose. Mapping the file is read-only, but changing kernel resume settings is a separate, system-wide action outside this inspection workflow.

tree-stats prints tree sizes and statistics and takes a device rather than a mount point. It needs root privileges.

sudo btrfs inspect-internal tree-stats /dev/mapper/data
sudo btrfs inspect-internal tree-stats -b /dev/mapper/data

In btrfs-progs 6.6.3, the short option documented for raw byte numbers is -b; use whichever spelling the installed command's help output accepts if you script this. If the filesystem is mounted, ongoing writes can make results inaccurate or produce warnings, so schedule a quiet period for a stable measurement and record the mount state with findmnt.

Done means

  • Checked the version. You confirmed the installed version and selected the correct Btrfs path or device.
  • Identified the subvolume. You used rootid or subvolid-resolve to confirm identity where relevant.
  • Started narrow. You chose a narrow superblock or tree query before collecting a large dump.
  • Protected the output. You used --hide-names or otherwise protected the output when sharing diagnostics.
  • Treated force as exceptional. You used --force only as a forensic option, never a routine workaround.
  • Recorded everything. You checked the exit status and noted warnings, package version and device name.