Test XFS File I/O Safely with xfs_io
You will finish with a repeatable way to inspect a file, write a known pattern, read it back, and inspect its extent map with xfs_io. The examples use a temporary regular file, so they do not require an XFS mount or elevated privileges.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide targets xfs_io 6.6.0 from xfsprogs 6.6.0-1ubuntu2.1. Allow about fifteen minutes. You need a shell, the xfsprogs package, and enough space for a small scratch file. Do not point the write or allocation examples at a real data file until you have checked every path and offset.
1. Check the installed tool
Start with read-only version and help checks. These commands need no elevated privileges:
$ command -v xfs_io
/usr/sbin/xfs_io
$ dpkg-query -W -f='${Package} ${Version}\n' xfsprogs
xfsprogs 6.6.0-1ubuntu2.1
$ xfs_io -V
xfs_io version 6.6.0
$ xfs_io -c 'help pread'
The last command prints command-specific help. Keep it close at hand: xfs_io has many XFS and Linux I/O test operations, and short commands such as pwrite are easy to confuse with shell commands. The full installed manual is the authority for this particular build.
Checkpoint
Confirm that the reported binary and package are the ones you intend to test. If you are investigating a production problem, record this version with the test results.
2. Create an isolated scratch file
Make a private temporary directory and keep its path in a shell variable. The directory is ordinary user state, so sudo is not needed:
$ TEST_DIR=$(mktemp -d /tmp/xfs-io-guide.XXXXXX)
$ TEST_FILE="$TEST_DIR/file"
$ printf 'scratch path: %s\n' "$TEST_FILE"
scratch path: /tmp/xfs-io-guide.abc123/file
$ xfs_io -f "$TEST_FILE" -c 'stat'
fd.path = "/tmp/xfs-io-guide.abc123/file"
fd.flags = non-sync,non-direct,read-write
stat.type = regular file
stat.size = 0
-f creates the file if it does not exist. The exact inode and block lines vary by filesystem. The important checks are that the path is the scratch path, the object is a regular file, and the initial size is zero. If the path is wrong, stop and fix the variable before using any write command.
When the test is complete, remove only the temporary directory you created, after checking its value:
$ printf 'review before removal: %s\n' "$TEST_DIR"
$ rm -rf -- "$TEST_DIR"
This removal is irreversible. Do not substitute a broad directory or an unset variable.
3. Write and read a known pattern
pwrite writes a range at an explicit byte offset. With no input file, -S selects the repeated fill value. The default block size is 4096 bytes, but this small test writes one operation cleanly:
$ xfs_io -f "$TEST_FILE" -c 'pwrite -S 0x41 0 16'
wrote 16/16 bytes at offset 0
16.000000 bytes, 1 ops; 0.0000 sec (...)
$ xfs_io "$TEST_FILE" -c 'pread -v 0 16'
00000000: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
read 16/16 bytes at offset 0
The timing text is variable and is shortened above. The stable evidence is 16 bytes written, 16 bytes read, and the expected byte value 41, which is ASCII A. pread does not change the file. Use -q when you need only the operation result without a buffer dump.
Verify the resulting size and contents independently if the test matters:
$ stat -c 'size=%s bytes' "$TEST_FILE"
size=16 bytes
$ od -An -tx1 "$TEST_FILE"
41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
Common trap: offsets and lengths are bytes, not filesystem blocks. A write at offset 4096 creates a hole between the old end of file and the new data. That is useful for testing sparse-file behaviour, but surprising if you meant to append.
4. Inspect allocation and file state
Use stat for the file size and flags, then fiemap to ask the filesystem for the file's extent map:
$ xfs_io "$TEST_FILE" -c 'stat' -c 'fiemap -v'
fd.flags = non-sync,non-direct,read-write
stat.type = regular file
stat.size = 16
extent 0: startoffset: 0..0, startblock: ..., length: 1...
...
The exact extent numbers depend on the backing filesystem and allocator. fiemap reports offsets and lengths in 512-byte units, not necessarily the filesystem block size. It is an observation tool, not a promise that physical placement will remain unchanged after later writes.
For a machine-readable filesystem extent report, use fsmap -m on a file whose filesystem supports the required interface. The output describes filesystem-wide ownership, including metadata and free regions, so it is more detailed than fiemap. Ask for help first:
$ xfs_io "$TEST_FILE" -c 'help fsmap'
5. Separate routine tests from dangerous commands
Most file tests above operate on the open file. The command-line form can open a file and run several commands in sequence:
$ xfs_io "$TEST_FILE" \
-c 'stat' \
-c 'pread -q 0 16' \
-c 'fiemap'
-c commands can be repeated over open files where that makes sense. -C restricts a command to the current open file. In an interactive session, type xfs_io "$TEST_FILE" and use help, stat, pread and quit. The command-line form is easier to keep in a ticket because the sequence is visible.
Do not casually run freeze, shutdown, inject, repair or resblks. The manual marks several filesystem commands as expert-only and privileged. shutdown can prevent further I/O, while error injection and repair can disrupt a filesystem or alter metadata. They belong in a controlled test environment with a recovery plan, not in a copy-and-paste diagnostic.
Likewise, pwrite, truncate, falloc, fpunch, fzero, reflink and dedupe can change file contents, allocation or metadata. Use a scratch file first. If you changed a real file, stop writes, preserve evidence, and restore it from the known-good copy or backup appropriate to your system; xfs_io does not provide a general undo command.
Done means
- You recorded the installed
xfs_ioandxfsprogsversions. - You confirmed the test path before creating or writing the file.
pwritewrote the requested byte count andpreadreturned the expected pattern.- You checked file size and, when useful, inspected extents with
fiemap. - You kept privileged filesystem operations out of routine testing.
- You know which temporary directory can be removed when the test is over.