Filesystem Types
A filesystem is the on-disk format that turns a raw block device into a tree of named files and directories: it decides how inodes, data blocks, free space, and metadata are laid out, and how that layout survives a crash. Linux supports dozens of them through the Virtual File System (VFS) layer, but on a Debian or Ubuntu server you will meet four that matter in practice — ext4, XFS, Btrfs, and ZFS — plus a handful of special-purpose formats like vfat, exFAT, and tmpfs.
The choice is not cosmetic. It fixes your maximum volume and file size, whether you can shrink a partition online, whether you get checksums and snapshots, and how the volume behaves when power is cut mid-write. Ubuntu installs ext4 by default; Red Hat Enterprise Linux and its rebuilds default to XFS. Once a filesystem is created with mkfs, most of these properties are locked in — you reformat to change them — so picking the wrong one is a migration, not a tweak.
The journaling extent filesystems: ext4 and XFS
ext4 is the conservative default. It uses extents (contiguous block ranges) instead of the indirect-block maps of ext2/ext3, journals metadata by default, and supports volumes up to 1 EiB and files up to 16 TiB with the standard 4 KiB block size. It can be grown online with resize2fs and, uniquely among the four, shrunk offline. Its weakness is fixed inode allocation: the inode count is set at mkfs time, so a volume full of tiny files can exhaust inodes while still showing free space in df.
XFS is the high-throughput alternative and the RHEL default. It allocates inodes dynamically, scales to 8 EiB volumes, and parallelizes I/O across allocation groups, which makes it strong for large files, many concurrent writers, and database workloads. The catch that surprises people: an XFS filesystem can be grown with xfs_growfs but cannot be shrunk at all. If you over-provision an XFS volume, the only way back is backup, recreate smaller, restore.
# Create and grow on Debian/Ubuntu — ext4 vs XFS mkfs.ext4 /dev/vdb1 resize2fs /dev/vdb1 # online grow to fill the device; -M to shrink (unmounted) mkfs.xfs /dev/vdb2 xfs_growfs /mnt/data # takes the MOUNT POINT, not the device; grow only
Copy-on-write filesystems: Btrfs and ZFS
Btrfs and ZFS are copy-on-write (CoW): they never overwrite live data in place, which gives them atomic snapshots, per-block checksums that detect silent corruption, transparent compression, and built-in volume management. Btrfs ships in the mainline kernel and is installed with apt install btrfs-progs; it supports subvolumes, send/receive replication, and RAID 0/1/10. Its parity RAID modes (raid5/raid6) still carry a known write-hole risk and are not recommended for production data.
ZFS is the more mature CoW system — end-to-end checksums, RAID-Z with no write hole, ARC caching, and dataset-level tunables. On Ubuntu it is packaged as zfsutils-linux and supported by Canonical, but it ships as a separate CDDL-licensed kernel module rather than in the mainline tree, so kernel upgrades occasionally break the DKMS build until a matching module appears. Both CoW filesystems trade some random-write performance and free-space predictability for their integrity and snapshot features; a CoW volume reporting 20% free can still fragment badly under constant rewrites.
# Snapshots: cheap, instant, metadata-only on both btrfs subvolume snapshot -r /data /data/.snap/2026-05-30 zfs snapshot tank/data@2026-05-30 zfs rollback tank/data@2026-05-30 # revert the dataset to the snapshot
Special-purpose and portable formats
Not every mount needs a journaling extent filesystem. The EFI System Partition must be FAT32 (vfat) because UEFI firmware can only read FAT; this is why /boot/efi is always vfat regardless of what the root filesystem is. For USB drives shared with Windows and macOS, exFAT (apt install exfatprogs) handles files larger than FAT32's 4 GiB ceiling. None of these have POSIX permissions or journaling, so they are wrong for a Linux root or data volume.
RAM-backed and pseudo filesystems fill the rest of the tree. tmpfs stores files in RAM (and swap), which is why /run, /dev/shm, and often /tmp are tmpfs — fast and automatically cleared on reboot. proc, sysfs, and cgroup2 are not real filesystems at all; they expose kernel data structures as files. You will see all of these in findmnt output, and they are managed by systemd and the kernel, not by entries you write yourself.
| Filesystem | Max volume | Shrink | Checksums / snapshots | Typical use |
|---|---|---|---|---|
| ext4 | 1 EiB | Yes (offline) | No | General-purpose root, Ubuntu default |
| XFS | 8 EiB | No | No | Large files, databases, RHEL default |
| Btrfs | 16 EiB | Yes (online) | Yes | Snapshots, multi-device, root with rollback |
| ZFS | 256 ZiB | No (per-pool) | Yes | Integrity-critical storage, NAS, archives |
Inspecting and choosing
Before you act on a volume, identify what it already is. lsblk -f and blkid report the filesystem type and UUID of each block device, and findmnt shows what is mounted where, including the pseudo filesystems. Never guess from the device name or the mount point — the filesystem type lives in the superblock, and that is what mount reads to load the right driver.
# What is on each device, and what is mounted lsblk -f blkid /dev/vdb1 findmnt -t ext4,xfs,btrfs # filter to real on-disk filesystems
For a default server root, ext4 is the safe answer: it is the most tested, the easiest to repair with fsck, and the only one you can shrink without a CoW pool. Reach for XFS when a single volume holds many large files or a busy database. Choose Btrfs or ZFS when you specifically need snapshots, checksums, or built-in RAID — and accept that you are taking on a more complex storage layer and less predictable free-space accounting in return.
Default to ext4 when you might ever need to shrink the volume, when you want the simplest recovery story, or when you have no specific feature requirement. Choose XFS for high-throughput single-device workloads with large files — databases, media stores, log aggregation — where you will only ever grow the volume.
Choose Btrfs when you want snapshots and rollback on the mainline kernel without a separate module, accepting that parity RAID is still unsafe. Choose ZFS when data integrity is the priority and you can manage an out-of-tree kernel module — for example a backup target or NAS where checksums and RAID-Z matter more than the kernel-upgrade friction.
- Provisioning an XFS volume larger than needed and later trying to shrink it — XFS has no shrink path, so you are forced into a full backup, recreate, and restore cycle.
- Formatting a volume of millions of tiny files with default ext4 inode density and then hitting "No space left on device" while df shows gigabytes free — the inodes are exhausted, and inode count is fixed at mkfs time.
- Putting the EFI System Partition on ext4 or XFS — UEFI firmware can only read FAT, so the machine fails to boot because it cannot find the loader in /boot/efi.
- Running ZFS or Btrfs raid5/raid6 for production data — Btrfs parity RAID still has an unfixed write hole, and ZFS RAID-Z geometry cannot be reshaped after pool creation.
- Assuming a CoW filesystem reporting free space can absorb writes — Btrfs and ZFS can return ENOSPC while df looks healthy, because metadata, snapshots, and CoW fragmentation consume real space.
- Calling xfs_growfs /dev/vdb2 with the device path instead of the mount point and getting an error — XFS grow operates on the mounted filesystem, so it expects the mount point.
- Trusting the device name or mount point to infer the filesystem type instead of reading the superblock with lsblk -f or blkid, then running the wrong repair or tuning tool.
- Confirm a volume's real type with blkid or lsblk -f before running any mkfs, resize, or fsck command against it.
- Default to ext4 for general-purpose roots and any volume you might need to shrink; reserve XFS for grow-only, large-file, throughput-heavy workloads.
- For volumes holding many small files, raise inode density at format time with mkfs.ext4 -i 8192 (bytes per inode) rather than discovering the limit in production.
- Layer ext4 or XFS on LVM when you want flexible resizing without committing to a CoW filesystem, so you can extend the logical volume and then resize2fs or xfs_growfs.
- If you adopt Btrfs or ZFS, monitor real usage with btrfs filesystem usage or zpool list instead of df, and schedule periodic scrub runs to catch silent corruption.
- Keep the EFI System Partition as vfat and use exFAT only for removable media shared with other operating systems, never for a Linux data volume.
- On Ubuntu with ZFS, pin or test kernel upgrades against the matching zfsutils-linux DKMS module before applying them to a host whose root pool is ZFS.
Knowledge Check
A team over-provisioned a 4 TB volume formatted with XFS and now wants to reclaim half of it for another mount. What is the realistic path?
- Unmount the volume and run xfs_growfs with a smaller -D block-count target to shrink it down in place.
- Back up the data, recreate a smaller filesystem, and restore — XFS cannot shrink.
- Unmount it and run resize2fs -M to reduce it to the minimum.
- Mount it read-only and use fsck.xfs to compact and resize the volume.
df shows 40 GB free on an ext4 volume, but writes fail with "No space left on device." What is the most likely cause?
- The ext4 journal has filled up and must be force-checkpointed before any new writes are allowed to resume.
- The volume needs resize2fs to claim space the partition table added.
- The inode table is exhausted — many tiny files used up the fixed inode count.
- XFS-style dynamic inode allocation has not been enabled on the volume.
Why must /boot/efi be formatted as vfat rather than ext4?
- UEFI firmware can only read FAT, so the bootloader must live on a FAT partition.
- ext4's metadata journal writes overlap the NVRAM-backed EFI variable store and corrupt it during an unclean shutdown.
- FAT is required because the EFI partition has no inode support in ext4.
- GRUB writes its core image in a FAT-only format that ext4 cannot store.
A backup server needs end-to-end checksums and RAID with no write hole, and the admin can tolerate occasional friction at kernel-upgrade time. Which filesystem fits best?
- ext4 layered on mdadm RAID, because it journals metadata and is by far the most thoroughly battle-tested of the four.
- XFS, because its allocation groups give it the strongest data integrity.
- ZFS, for RAID-Z and per-block checksums, accepting its out-of-tree kernel module.
- Btrfs in raid6, since its parity mode is the safest of the four options.
You got correct