Read XFS Extents Safely with xfs_bmap

When a file feels slower than it should, xfs_bmap shows exactly how it is laid out on disk: extents, holes, allocation groups.

The commands here only read metadata; nothing defragments, rewrites or deletes the file.

Allow about ten minutes. You need the xfsprogs package, a readable file on XFS, and enough access to query that filesystem. The examples use xfsprogs 6.6.0, where the installed program reports xfs_bmap version 6.6.0. Other releases can format diagnostics differently.

Checkpoint: this is an observation guide. It does not create an XFS filesystem or change allocation. Do not test it against a guessed path on an ext4, Btrfs or network filesystem.

1. Confirm the installed command and filesystem

Check which executable is being used and the package version first, both ordinary read-only commands:

$ command -v xfs_bmap
$ xfs_bmap -V
xfs_bmap version 6.6.0
$ dpkg-query -W -f='${Package} ${Version}\n' xfsprogs

Now replace /path/to/file with the real file you want to inspect, and ask the kernel which filesystem contains it:

$ findmnt -T /path/to/file -o TARGET,FSTYPE,SOURCE
$ test -r /path/to/file && echo readable

The filesystem type must be xfs. If it is not, stop: xfs_bmap is specifically for XFS files and rejects a foreign filesystem, it does not translate another filesystem's layout into an XFS map.

2. Print the ordinary data-fork map

Run the simplest query with the file path as the final argument:

$ xfs_bmap /path/to/file

Output is one line per extent, shaped like extent: [startoffset..endoffset]: startblock..endblock. A hole shows in place of the physical block range.

Warning: the offset and block numbers are always measured in 512-byte units, even when the XFS filesystem uses a different block size. That is the first trap: do not divide by the filesystem block size, and do not read them as byte offsets without multiplying by 512. A fragmented file shows several lines; a file with no data blocks shows holes, not an error.

Checkpoint: record the output before changing anything else. It is your baseline for comparing a later investigation or storage event.

3. Make the extent length visible

Add -l for each line to include the number of 512-byte blocks in that extent:

$ xfs_bmap -l /path/to/file

Useful when counting blocks or comparing adjacent ranges. Do not combine it with -v expecting both forms: the manual says -l has no effect once verbose output is selected.

Exploring a badly fragmented file, use -n followed by the maximum number of extents to keep the map readable:

$ xfs_bmap -n 20 /path/to/file

That is an output limit, not a byte-range selection. It changes nothing about the file, and it does not mean the file only contains that many extents.

4. Add allocation-group details when needed

Use -v for verbose output, which appends allocation-group information, the extent length and a flags field to each line:

$ xfs_bmap -v /path/to/file

The flags separate ordinary allocated extents from states that matter during filesystem analysis. Run a second -v for the flags legend too:

$ xfs_bmap -vv /path/to/file

Do not turn verbose output into a fixed parser without testing against the installed release. Allocation-group numbers and offsets are filesystem-specific, and the diagnostic presentation can change between xfsprogs versions.

5. Check special extents without flushing pages

Two options expose states the default query skips:

$ xfs_bmap -p -v /path/to/file
$ xfs_bmap -e -v /path/to/file

These still only inspect, but their results describe a live filesystem state: a process writing the file can change the answer between runs. Need a stable comparison? Coordinate with the application owner and use a proper maintenance window rather than stopping a service just to make a map look tidy.

6. Inspect the attribute fork separately

XFS can store extended attributes in an attribute fork rather than the ordinary data fork. Use -a when that fork is specifically what you're investigating:

$ xfs_bmap -a -v /path/to/file

This switches what gets printed; it is not an extra view appended to the normal data map. Diagnosing file contents or ordinary fragmentation, omit -a. Diagnosing extended-attribute storage, note that you selected the attribute fork so a later reader does not mistake the result for the data layout.

7. Handle failures without reaching for sudo

A foreign-filesystem message means the target is not on XFS, or the path resolved somewhere unexpected. Recheck it:

$ readlink -f /path/to/file
$ findmnt -T /path/to/file -o TARGET,FSTYPE,SOURCE

A missing or unreadable path is a path or permission problem, checked without touching the file:

$ ls -l /path/to/file
$ test -r /path/to/file && echo readable

Normally xfs_bmap needs no elevated privileges when you can read the target and query its mounted filesystem. If the host's access policy denies the query, ask the system owner to run it, or use the minimum approved privilege for that host.

Warning: do not use sudo as a way to make an ext4 or Btrfs path suitable for xfs_bmap; it never will be.

Nothing here needs undoing, since none of the examples change state. If a script captured output to a file, remove or replace only that report per your normal retention policy; the inspected XFS file stays untouched throughout.

Done means