Skip to main content
RunBook Academy

LinuxXIV · Filesystemsxfs

XFS deep dive - features, tuning, and operations

Intermediate⏱ ~12 minbashmkfs.xfsxfs_infoxfs_growfsxfs_dbxfs_scrub

What you'll learn

  • Explain XFS allocation groups, B+trees, and journal types
  • Tune XFS for performance on large filesystems
  • Run online defragmentation, scrub, and resize
  • Use xfs_info and xfs_growfs effectively

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

XFS is the default filesystem for RHEL-family distributions and a strong choice for large data filesystems. It is designed for throughput, has a robust journal, and supports online operations that ext4 does not.

Creating an XFS filesystem

Confirm the target device before you format it. mkfs.xfs does not ask for confirmation and does not care whether the device is your data volume or your root disk.

Read-only / Safeconfirm the target
$ lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS /dev/vg_data/data && blkid /dev/vg_data/data
NAME         SIZE TYPE FSTYPE MOUNTPOINTS
vg_data-data 1T   lvm
Data-loss riskmkfs.xfs
# mkfs.xfs -L data -l size=512m -d agcount=16 /dev/vg_data/data
meta-data=/dev/vg_data/data      isize=512    agcount=16, agsize=8388608 blks
data     =/dev/vg_data/data      bsize=4096   blocks=268435456, imaxpct=25
=/dev/vg_data/data      sectsz=512   sunit=0      blks, rw
naming   =version 2              bsize=4096   ascii-ci=0
log      =internal log           bsize=4096   blocks=131072, version=2
=/dev/vg_data/data      sectsz=512   sunit=0      blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

Mount options

Configuration changexfs mount options
$ mount -o noatime,allocsize=64m,logbufs=8 /dev/vg_data/data /data

Operations

Growing an XFS filesystem

Configuration changexfs_growfs
$ xfs_growfs /data
meta-data=/dev/vg_data/data      isize=512    agcount=16, agsize=15728640 blks
data     =/dev/vg_data/data      bsize=4096   blocks=629145600, imaxpct=25

Shrinking an XFS filesystem

You cannot. This is the single most important operational fact about XFS.

There is no xfs_shrink. xfs_growfs only grows - the manual page calls it “expand an XFS filesystem”. xfs_repair is a metadata consistency checker and repairer; it has no resize option at all and will not make a filesystem smaller. Nothing in xfsprogs reduces the size of a live XFS filesystem.

Recent xfsprogs annotate the xfs_growfs -D option with “Only shrinking the last AG without removing it is implemented”. Do not read that as a shrink path. It cannot remove an allocation group, it cannot reclaim a meaningful amount of space, and it will not help you hand extents back to a volume group. Treat XFS as grow-only.

The supported way to reduce an XFS filesystem is to build a new, smaller one and move the data into it:

  1. Back up the filesystem: xfsdump to a file or tape, or rsync -aHAX to another volume. Verify the backup can be read.
  2. Stop everything that writes to the mount point, then unmount it.
  3. Create the smaller volume: lvcreate -L 50G -n data-new vg0. Building alongside the old volume means the old data is still there if the restore fails.
  4. Format it: mkfs.xfs /dev/vg0/data-new.
  5. Restore into it: xfsrestore, or rsync -aHAX from the backup.
  6. Verify file counts, sizes, ownership, and ACLs before you trust the copy.
  7. Swap the mount: update /etc/fstab to the new volume, mount, and confirm the application works.
  8. Only after that, remove the old volume with lvremove to reclaim the space.

The practical lesson is to size XFS volumes conservatively. Start smaller than you think you need and grow with xfs_growfs, which is cheap and online. Over-provisioning an XFS volume is a mistake you pay for with a full backup and restore.

Online scrub

xfs_scrub takes a mount point, not a block device. The synopsis is xfs_scrub [ -abCeMmnpTvx ] mount-point. Passing /dev/sda1 is invalid usage and the command will not run.

Read-only / Safexfs_scrub -n (check only)
# xfs_scrub -n /data

Without -n, xfs_scrub is not a check. The manual page is explicit: if the kernel reports that metadata needs repairs or optimisations and you did not pass -n, the program asks the kernel to make those repairs and perform those optimisations. That is a write to a live, mounted, in-use filesystem.

Data-loss riskxfs_scrub (repair mode)
# xfs_scrub /data

Defragmentation

Configuration changexfs_fsr
$ xfs_fsr /data
xfs_fsr -m /data

Filesystem check

Read-only / Safexfs_repair -n
$ xfs_repair -n /dev/vg_data/data
Phase 1 - find and verify superblock...
Phase 2 - scan filesystems for bad magic numbers...
Phase 3 - scan inodes for bad magic numbers...
done

Knowledge check

Knowledge check · 5 questions

  1. Q1. What is the maximum size of an XFS filesystem?

  2. Q2. XFS supports online shrink of a mounted filesystem.

  3. Q3. Which of the following are correct for XFS production? Select all that apply.

  4. Q4. A colleague has added `xfs_scrub /srv/data` to the monthly cron on every production database host, describing it as a read-only health check. What is wrong with that?

  5. Q5. A host has just come back from a power cut. Its XFS data filesystem is mounted and the application is running. What should you do first?

Passing score: 75%. Answers are checked in this browser.