On this page

ZFS — Not Part of the Kernel, But Unavoidable

Overview: ZFS Architecture (ZPL/DMU/SPA/ZIL/ARC) → COW Transaction Model → Integration with Linux VFS (SPL) → Comparison with Btrfs/bcachefs → Licensing Issues

Why ZFS is Not in the Linux Kernel

ZFS uses the CDDL license, which is incompatible with Linux's GPLv2. Sun/Oracle chose not to dual-license, meaning ZFS can never be merged into the mainline Linux kernel.

Solution: OpenZFS is provided as a kernel module, compiled and installed via DKMS. The interface between the CDDL module and the GPL kernel is abstracted through the SPL (Solaris Porting Layer). The licensing controversy centers on "whether it constitutes a derivative work"—a legal gray area—so different distributions handle it differently:

  • Ubuntu: Packages zfs-dkms directly
  • Debian: Available in the contrib repository
  • Fedora/RHEL: Not officially supported (users compile themselves)

ZFS Architecture Stack

ZFS Architecture Stack: Call Hierarchy from User Space to Physical Devices User Space — zfs(1) / zpool(1) / libzfs Kernel (OpenZFS module) ZPL (ZFS POSIX Layer) — VFS Interface (i_op / f_op, etc.) zfs_znode → corresponding inode → zfs_vnode_ops → VFS file_operations DMU (Data Management Unit) — Mapping of Transaction Objects to Blocks dnode → Object (file/directory/attribute) · dmu_tx → Transaction · dnode → Block Pointer Tree (indirect blocks) ZIL (ZFS Intent Log) — Synchronous Write Journal zil_commit() → Writes to ZIL device (SSD/HDD partition), accelerating fsync (sync writes bypass large transactions) ARC (Adaptive Replacement Cache) — Read Cache MRU (Most Recently Used) + MFU (Most Frequently Used) · More advanced than page cache, configurable via zfs_arc_max SPA (Storage Pool Allocator) — Physical Device Management Layer metaslab → Free space management · space map → Log-based tracking · Allocation strategies: first-fit / best-fit VDEV (Virtual Device) — RAID / Device Abstraction disk · mirror · raidz(1/2/3) · special (metadata/dedup) · cache (L2ARC) · log (ZIL/SLOG)

COW Transaction Model

For each write operation:
  1. Allocate a new block (find free space in the target metaslab)
  2. Write new data to the allocated block
  3. Update the dnode's block pointer (point to new block, not old block)
  4. dnode changed → dnode itself must be written to new location → Update upper-level pointers
  5. Propagate upwards → uberblock (root) update → Atomic completion

Key: All pointer updates are atomic (single write to uberblock)
  → After a crash, you either see the old state or the new state — no intermediate state
  → This is the guarantee of "no journal" (COW itself ensures consistency)

Transaction Grouping (TXG):
  ZFS merges write operations from multiple system calls into a single Transaction Group (TXG)
  Committed every ~5 seconds (zfs_txg_timeout)
  → Reduces fragmentation, improves write throughput
  → fsync bypasses this delay: uses ZIL for independent commit

SLOG and ZIL

ZIL (ZFS Intent Log):
  Accelerator for synchronous writes (O_SYNC / fsync)
  Normal async writes → Every 5 seconds TXG → No ZIL needed
  Sync writes → ZIL records separately → Returns to user space → Fast
         → TXG commit after 5 seconds → ZIL records can be discarded

SLOG (Separate LOG):
  Place ZIL on a dedicated device (low-latency NVMe SSD)
  Sync write latency drops from HDD latency to SSD latency
  Crash recovery: Replay ZIL + recent TXG → Full recovery

ZIL is NOT a write cache!
  It only stores operation logs → Data is always written to main storage by TXG
  Power loss loses ZIL → Only loses sync writes from the last 5 seconds (async writes unaffected)

Comparison with Btrfs/bcachefs

ZFSBtrfsbcachefs
LicenseCDDLGPLv2GPLv2
Kernel IntegrationDKMS modulein-treein-tree (6.7+)
COWAlwaysMetadata always, Data optionalAlways
SnapshotsZVOL, dataset levelsubvolumesubvolume
RAIDraidz(1/2/3), mirrorraid0/1/10/5/6Multi-device tiering
ARC/L2ARCYesNo (uses page cache)No
DeduplicationOnline (very memory intensive)Offline (tools available)No
Built-in Compressionlz4, zstd, gzipzstd, lzo, zlibzstd, lz4, gzip
Send/Receivezfs send/recvbtrfs send/receivePlanned

ZFS's clear advantages are maturity (20+ years of production deployment) and the ARC read cache. Btrfs's advantages are mainline kernel integration and lighter-weight RAID. bcachefs is too new, and its stability remains to be verified.


Debugging

# ARC status (requires zfs installation)
cat /proc/spl/kstat/zfs/arcstats

# Pool status
zpool status
zpool iostat -v 1

# Current TXG
cat /sys/module/zfs/parameters/zfs_txg_timeout

References and Further Reading

  • OpenZFS Documentation: https://openzfs.github.io/openzfs-docs/
  • Source Code: https://github.com/openzfs/zfs
  • Key Papers:
    • "The Zettabyte File System" (Sun, 2003)
    • "The Adaptive Replacement Cache" (Megiddo & Modha, 2003)

Keywords: ZFS, DMU, ZIL, ARC, SPA, COW, SLOG, dnode, uberblock, TXG, CDDL, DKMS