Storage and file systems

Blocks, journals and consistency, how ext4, NTFS and APFS differ, copy-on-write snapshots, SSD wear levelling and TRIM, and what fsck can and cannot fix.

From a write() to a platter or a cell

application  write(fd, buf, n)
                 |
             page cache            <- the write returns here, often before it is durable
                 |
         file system            blocks, journal, metadata
                 |
         block layer            merges and orders requests, does I/O scheduling
                 |
         device driver / device  SSD or spinning disk

fsync(fd) forces the data out of the page cache;
durability requires it, and it costs a device round trip.
  • A write without fsync survives a process crash but not a power loss; the bytes may still be in the page cache.
  • A journal records metadata changes so the file system can be replayed into a consistent state after a crash.
  • Journal modes differ in what they protect: metadata only, or data as well. Data journalling is slower and safer.
  • Atomic replace writes to a temporary file, fsyncs it, then renames — the rename is what makes the swap atomic.
sync                                # flush all dirty pages
fstrim -av                          # inform the SSD which blocks are free
mount | grep -E "ext4|xfs|btrfs|apfs"
stat -f /                           # file system type and block size

Comparing the file systems you will meet

File systemPlatformNotable designSnapshots
ext4LinuxJournal, extents, mature toolingNo native support
XFSLinuxExcellent large-file throughput, online growthNo, use LVM or a storage layer
BtrfsLinuxCopy-on-write, checksums, subvolumesYes, cheap and instant
ZFSLinux, BSDChecksums, pools, snapshots, integrity focusYes, plus replication
NTFSWindowsJournal, access control lists, alternate data streamsVia shadow copies
APFSmacOSCopy-on-write, space sharing, snapshotsYes, local and integrated
FAT32 / exFATRemovable mediaNo journal, no permissionsNo

Copy-on-write file systems never overwrite a block in place, which is what makes snapshots cheap: a snapshot is a reference to the old block pointers. It also means fragmentation grows over time and free space is not freed until every snapshot referencing it is gone.

SSD behaviour worth knowing

  • A cell must be erased before it is rewritten, so writes go to fresh blocks and the old ones are erased later by garbage collection.
  • Wear levelling distributes writes across cells, and the endurance rating is a total bytes written figure, not a lifespan in years.
  • TRIM tells the device which blocks are no longer in use, which keeps garbage collection efficient and preserves write performance.
  • Random writes amplify: writing 4 KB can trigger a much larger internal erase. Aligning partitions to the device's erase blocks reduces this.
  • A nearly full SSD has few free blocks, so garbage collection works harder and latency rises. Keep spare capacity above about ten percent.
# check device health and endurance
smartctl -a /dev/nvme0 | grep -E "Percentage Used|Data Units Written|Media Errors"
smartctl -a /dev/sda | grep -E "Reallocated|Pending|Wear_Leveling"

# is a periodic trim enabled?
systemctl status fstrim.timer

# block sizes and alignment
lsblk -o NAME,SIZE,PHY-SEC,LOG-SEC,MOUNTPOINT
⚠️
A file can be deleted and the space still not reclaimed because a process holds it open. Check with lsof +L1 before concluding that du is lying — a full disk with nothing to find is almost always a deleted-but-open file.

FAQ

Do I need fsync for every write?
Only when durability matters for correctness. Batch fsyncs per transaction, not per record, or throughput collapses to the device's round trip time.
Can fsck recover my data?
It restores file system consistency, not file contents. It can lose data in the inodes it repairs, which is why a backup and a checksumming file system are the real protection.

Monitoring and troubleshooting Containers, namespaces and cgroups

Last refreshed 2026-09-18.