Never Destroy What You Have
Traditional filesystems — ext4, NTFS, FAT32 — are overwrite (or update-in-place) systems. When you modify a file, the filesystem locates the existing data blocks on disk and overwrites them with new content. The old data is gone the moment the write begins.
Modern filesystems — Btrfs (B-tree filesystem) and ZFS (Zettabyte File System) — use Copy-on-Write (CoW). The name describes the behavior precisely: when you write to an existing location, the filesystem copies the data to a new location first, then writes there.
The CoW Sequence
- You modify a file. The filesystem allocates new, empty blocks elsewhere on disk.
- The new data is written to those new blocks.
- Only after the write succeeds does the filesystem update the metadata (inode, block pointers) to reference the new blocks.
- The old blocks are marked free — unless something else (like a snapshot) is still referencing them.
Why this eliminates the half-written problem: At no point is valid data overwritten. The old blocks remain intact and correct until the new blocks are fully written and the pointer is atomically updated. A crash at any point leaves either the old version (if the pointer was not updated) or the new version (if it was) — never a mix of both.
Trade-offs of CoW
CoW is not free. Writing a 4 KB change to a file requires allocating new blocks, writing data, and updating metadata — more I/O operations than a simple overwrite. On workloads with many small random writes (databases, for example), CoW can cause write amplification and fragmentation over time, because data that was once contiguous gets scattered across the disk as it is repeatedly copied to new locations.
This is why PostgreSQL and MySQL are typically run on ext4 or XFS rather than Btrfs — the database manages its own write ordering and crash recovery internally, and CoW's overhead is a net negative. Btrfs and ZFS shine for general-purpose storage, backups, NAS workloads, and container image layers.