XFS, end to end: grow it, repair it, and why it can't shrink
XFS is the default on RHEL, AlmaLinux and Rocky, and the filesystem of choice for large files and parallel I/O. It’s also the clearest example of an asymmetric filesystem: it grows beautifully and, in practice, never shrinks. The videos show the commands; this page explains why they work.
Same model as always: disk → partition → filesystem, on a disposable 2 GB scratch disk.
Create it
sudo parted -s /dev/sdb mklabel gpt
sudo parted -s /dev/sdb mkpart primary xfs 1MiB 1GiB
sudo mkfs.xfs -f -L data /dev/sdb1
sudo mkdir -p /mnt/xfslab
sudo mount /dev/sdb1 /mnt/xfslab
mkfs.xfs prints the geometry (block size, allocation groups, log); -L sets
the label; -f forces it over an existing signature. Prove it with the same
round-trip as any filesystem: write, unmount, mount, read.
On GPT, the first mkpart argument (primary) is the partition’s name, not
a type. data would be a clearer name; either works.
echo 'hello from xfs' | sudo tee /mnt/xfslab/hello.txt
sudo umount /mnt/xfslab
sudo mount /dev/sdb1 /mnt/xfslab
sudo cat /mnt/xfslab/hello.txt
sudo xfs_info /mnt/xfslab
sudo blkid /dev/sdb1
Grow it
XFS grows online, while mounted:
sudo growpart /dev/sdb 1 # grow the partition first
sudo xfs_growfs /mnt/xfslab # then the mounted filesystem
xfs_growfs takes the mountpoint, not the device. It extends the filesystem
to fill the partition. This is the normal XFS growth path: add space, grow the
partition, grow the mount.
growpart is not always installed: on Debian/Ubuntu it comes from
cloud-guest-utils, on the RHEL family from cloud-utils-growpart.
Check and repair it
xfs_repair is an offline tool. Unmount first, check without modifying, then
repair:
sudo umount /mnt/xfslab
sudo xfs_repair -n /dev/sdb1 # check only
sudo xfs_repair /dev/sdb1 # repair
sudo mount /dev/sdb1 /mnt/xfslab
On a clean filesystem the repair is a no-op with a full phase report — which is
exactly what you want to see before you trust it. Never run xfs_repair on a
mounted filesystem.
If the filesystem was not unmounted cleanly, xfs_repair refuses to run and
points at -L, which zeroes the log. That can lose the last transactions, so
mount and unmount the filesystem first and let the log replay; use -L only as
a last resort.
Why XFS can’t shrink
This is the part of the series that matters most. Trying is the proof:
sudo xfs_growfs -D 262144 /mnt/xfslab; echo exit: $?
# xfs_growfs: XFS_IOC_FSGROWFSDATA xfsctl failed: Invalid argument
# exit: 1
The filesystem stays exactly the size it was. XFS is built around allocation groups and a design that favours parallel allocation and large files. There is no practical in-place shrink path: newer kernels and xfsprogs can trim unused space from the tail of the last allocation group (still experimental), but they can’t remove a whole AG — which is exactly what a 2 GB → 1 GiB shrink asks for. The practical alternatives are:
- Back up, recreate smaller, restore.
xfsdump/xfsrestore, orrsyncinto a new, smaller filesystem. - Pick a filesystem that can shrink (ext4 or Btrfs) when you know the disk will need to get smaller.
That asymmetry is not a bug to work around; it is a property to plan for.
What to remember
- XFS grows online but can’t shrink.
- Grow the partition first, then
xfs_growfsthe mountpoint. xfs_repairis offline; check with-nfirst.- For shrinking, plan a backup/recreate/restore — or choose ext4/Btrfs.
Part of Filesystems, end to end.