Linux Filesystems — ext4, XFS, Btrfs & ZFS Compared
In this tutorial, you'll learn about Linux Filesystems. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Linux offers multiple production filesystems, each with different strengths: ext4 for general reliability, XFS for large-scale throughput, Btrfs for integrated snapshots and checksums, and ZFS for enterprise storage pools with data integrity guarantees.
What You'll Learn
How ext4, XFS, Btrfs, and ZFS handle data integrity, snapshots, compression, scalability, and administration. You will see feature comparisons, performance benchmarks, and real-world recommendations for each workload type.
Why Filesystem Choice Matters
The filesystem is the most fundamental layer of data management. Choosing the wrong one means rebuilding servers later. Ext4 works everywhere but lacks checksumming. XFS handles millions of small files poorly. Btrfs and ZFS add data integrity but have memory and complexity costs. DodaZIP's object storage backend uses ZFS for checksummed block storage.
Learning Path
flowchart LR A[LVM Guide] --> B[RAID Config] B --> C[Filesystems Compared
You are here] C --> D[Swap Management] C --> E[Backup Strategies] style C fill:#f90,color:#fff
Feature Comparison
| Feature | ext4 | XFS | Btrfs | ZFS |
|---|---|---|---|---|
| First release | 2008 | 1994 | 2009 | 2005 |
| Max filesystem size | 1 EiB | 8 EiB | 16 EiB | 256 ZiB |
| Max file size | 16 TiB | 8 EiB | 16 EiB | 256 ZiB |
| Max files | 4 billion | Limited by space | Limited by space | Limited by space |
| Journal checksumming | No | No | Yes | Yes |
| Data checksums | No | No | Yes (CRC32C) | Yes (fletcher4, SHA256) |
| Snapshots | No | No | Yes | Yes |
| Compression | No | No | Yes (zstd, lzo, zlib) | Yes (lz4, gzip, zstd) |
| Deduplication | No | No | No (experimental) | Yes |
| RAID support | Via mdadm | Via mdadm | Native RAID 0/1/10/5/6 | Native RAID-Z |
| Online defrag | No | No | Yes | No (rewrite instead) |
| Shrink online | No | No | No | No |
| Send/receive | No | No | Yes (btrfs send) | Yes (zfs send) |
ext4 — The Reliable Default
# Create an ext4 filesystem
sudo mkfs.ext4 /dev/sdb1
# With specific options
sudo mkfs.ext4 -O ^has_journal -E stride=32,stripe_width=64 /dev/sdb1
# Tune mount options
sudo mount -o noatime,nodiratime,data=ordered /dev/sdb1 /mnt/data
# Check and repair
sudo fsck.ext4 -f /dev/sdb1
# Resize online
sudo resize2fs /dev/sdb1 # grows to fill device
sudo resize2fs /dev/sdb1 100G # shrink to 100G (unmount first)
ext4 Performance Tuning
# Disable access time updates (reduces writes)
sudo tune2fs -O ^has_journal /dev/sdb1 # Disable journaling (risky)
sudo tune2fs -m 1 /dev/sdb1 # Reserved blocks: 1% instead of 5%
# Check filesystem parameters
sudo tune2fs -l /dev/sdb1 | grep -E "Filesystem features|Block count|Reserved"
XFS — High-Performance Scalability
XFS excels at large files and parallel I/O. It is the default on RHEL 7+.
# Create XFS filesystem
sudo mkfs.xfs -f /dev/sdb1
# With stripe alignment for RAID
sudo mkfs.xfs -d su=64k,sw=8 /dev/sdb1
# Mount
sudo mount -o noatime,largeio,inode64,swalloc /dev/sdb1 /mnt/data
# Grow (XFS cannot shrink)
sudo xfs_growfs /mnt/data
# Check and repair
sudo xfs_repair -n /dev/sdb1 # Dry run
sudo xfs_repair /dev/sdb1 # Full repair (requires unmount)
# Dump metadata
sudo xfs_metadump /dev/sdb1 /tmp/metadump
XFS Quotas
# Enable project quotas
sudo xfs_quota -x -c 'project -s -p /mnt/data/project1 101' /mnt/data
sudo xfs_quota -x -c 'limit -p bsoft=10g bhard=12g 101' /mnt/data
# View usage
sudo xfs_quota -x -c 'report -p' /mnt/data
Btrfs — Snapshots, Checksums, and Flexibility
Btrfs is a copy-on-write filesystem with integrated volume management.
Creating a Btrfs Filesystem
# Single device
sudo mkfs.btrfs /dev/sdb1
# RAID 1 across two devices
sudo mkfs.btrfs -d raid1 -m raid1 /dev/sdb1 /dev/sdc1
# With compression enabled at creation
sudo mkfs.btrfs --csum crc32c /dev/sdb1
Subvolumes and Snapshots
# Create subvolumes
sudo btrfs subvolume create /mnt/data/@docker
sudo btrfs subvolume create /mnt/data/@home
# Snapshot
sudo btrfs subvolume snapshot /mnt/data/@docker /mnt/data/@docker-snap-20260624
# Send snapshot to another device
sudo btrfs send /mnt/data/@docker-snap-20260624 | \
sudo btrfs receive /mnt/backup/
# List subvolumes
sudo btrfs subvolume list /mnt/data
Btrfs Compression
# Mount with zstd compression
sudo mount -o compress=zstd:3 /dev/sdb1 /mnt/data
# Set compression per-file
chattr +c /mnt/data/largefile.log
Btrfs Scrub (Data Integrity Check)
# Start a scrub (read all data, verify checksums)
sudo btrfs scrub start /mnt/data
# Check scrub status
sudo btrfs scrub status /mnt/data
Expected output:
UUID: abcdef12-3456-7890-abcd-ef1234567890
Scrub started: Wed Jun 24 10:00:00 2026
Status: finished
Duration: 0:05:23
Total to scrub: 512.34GiB
Rate: 1.58GiB/s
Error summary: checksum=0, super=0
ZFS — Enterprise Storage with Integrity
ZFS combines a filesystem and volume manager with data integrity guarantees. Not in the mainline kernel — install via zfs-dkms or zfsutils-linux.
Creating a ZFS Pool
# Create a striped pool
sudo zpool create tank /dev/sdb /dev/sdc
# Create a RAID-Z pool (single parity)
sudo zpool create tank raidz /dev/sdb /dev/sdc /dev/sdd
# Create a mirrored pool
sudo zpool create tank mirror /dev/sdb /dev/sdc
ZFS Datasets (Filesystems)
# Create dataset with compression
sudo zfs create tank/data
sudo zfs set compression=lz4 tank/data
sudo zfs set quota=500G tank/data
sudo zfs set atime=off tank/data
# Create a volume (raw block device)
sudo zfs create -V 100G tank/docker-vol
# List datasets
sudo zfs list
# Get detailed properties
sudo zfs get all tank/data
ZFS Snapshots and Clones
# Snapshot
sudo zfs snapshot tank/data@20260624
# Clone a snapshot (writable copy)
sudo zfs clone tank/data@20260624 tank/data-clone
# Send snapshot to remote
sudo zfs send tank/data@20260624 | ssh backup-server sudo zfs receive backup/data
# Automated snapshots with zfs-auto-snapshot
sudo apt install zfs-auto-snapshot
# Cron job creates snapshots every 15min, hourly, daily, weekly
ZFS Scrub and Repair
# Start a scrub
sudo zpool scrub tank
# Check status
sudo zpool status tank
# View data errors
sudo zpool status -v tank
Expected output:
pool: tank
state: ONLINE
scan: scrub repaired 0B in 0 days 00:12:34 with 0 errors on Wed Jun 24 12:12:34 2026
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
errors: No known data errors
Performance Benchmarks
# Simple write benchmark
dd if=/dev/zero of=/mnt/data/test bs=1M count=1000 conv=fdatasync
# Using fio for realistic benchmarks
sudo fio --name=test --ioengine=libaio --direct=1 --bs=4k \
--size=1G --rw=randread --numjobs=4 --runtime=30 \
--directory=/mnt/data
# Compare sequential read throughput
sudo fio --name=seqread --ioengine=libaio --direct=1 --bs=1M \
--size=10G --rw=read --runtime=30 --directory=/mnt/data
Common Errors
1. Running Out of Inodes on ext4
ext4 pre-allocates inodes at mkfs time. If you store millions of tiny files, run df -i to check inode usage. Recreate the filesystem with -N to increase inode count.
2. XFS Cannot Shrink
XFS is a grow-only filesystem. Once created, you cannot shrink it. Plan partition sizes carefully. For resizable storage, use LVM beneath XFS.
3. Btrfs Out of Space with Free Space Showing
Btrfs allocates space in chunks. A filesystem can report free space but refuse writes if available chunks are fragmented. Run sudo btrfs filesystem usage /mnt/data to see chunk allocation vs free bytes.
4. ZFS ARC Consuming All Memory
ZFS uses ARC (Adaptive Replacement Cache) which defaults to 50% of system RAM. On systems with 256GB RAM, ARC takes 128GB. Limit it: echo "options zfs zfs_arc_max=8589934592" > /etc/modprobe.d/zfs.conf.
5. Btrfs Checksum Errors on Consumer SSDs
Consumer SSDs can silently return corrupted data. Btrfs detects this via checksums but cannot repair without redundancy. Always use RAID 1 or better for Btrfs on critical data.
6. ZFS Pool Import Fails After System Crash
Export the pool before rebooting: sudo zpool export tank. If a pool was not exported, force import: sudo zpool import -f tank.
7. ext4 Data Corruption on Power Loss with Write Cache
Consumer drives lie about flush completion. Disable the write cache: sudo hdparm -W 0 /dev/sdb. Or use a filesystem with checksums (Btrfs, ZFS).
Practice Questions
1. Which filesystem supports compression and checksums natively? Both Btrfs (zstd, CRC32C) and ZFS (lz4, fletcher4/SHA256) support inline compression and data checksums.
2. Can XFS be shrunk? No — XFS is grow-only. Plan accordingly or use LVM under XFS.
3. What is the main advantage of ZFS over Btrfs? ZFS has a mature RAID-Z implementation (software RAID with variable-width parity), deduplication, and decades of production use in enterprise storage. Btrfs RAID 5/6 is not production-ready.
4. How do you check if NFS data was corrupted on disk with ext4? Ext4 has no data checksums. You must rely on hardware ECC, SMART, and application-level checksums. This is a key reason to use Btrfs or ZFS for critical data.
5. What does sudo btrfs scrub start do?
It reads all stored data and metadata, verifies CRC checksums, and reports any corruption. On RAID configurations, it also repairs detected errors.
Challenge: Set up a two-disk system with Btrfs RAID 1 and ZFS mirror on separate disk pairs. Create identical datasets on both with compression enabled. Write 10GB of data, take a snapshot, corrupt one disk with dd, then verify how each filesystem detects and repairs the corruption. Document the experience.
What's Next
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-24.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro