On this page
Filesystem Implementation
Coverage: ext4 (extent tree/jbd2/delayed allocation) → XFS (AG/B+tree/reflink) → Btrfs (COW/subvolume/snapshot/checksum) → bcachefs (6.7+) Kernel versions: 2.6 ~ 6.x
Overview
Linux supports various local filesystems, each with different design philosophies:
- ext4: Stability-first, journal + delayed allocation, suitable for general-purpose scenarios
- XFS: Large-scale parallel I/O, Allocation Group (AG) design, suitable for large files and high concurrency
- Btrfs: COW + checksum + snapshot, suitable for NAS and scenarios requiring data integrity guarantees
- bcachefs: Next-generation COW filesystem (6.7+), copygc + multiple devices + compression
ext4: A Stable General-Purpose Solution
Extent Tree
// ext4 uses an extent tree to replace indirect blocks (indirect/double-indirect/triple-indirect in ext2/3)
// An extent describes: "file offset X ~ X+LEN maps to disk block Y ~ Y+LEN"
;
// The extent tree is a B-tree (located within the inode or in separate blocks)
// ext4_inode->i_data[60] = 4 ext4_extents + 1 header
// → The first 4 extents exist directly in the inode (no additional block read needed!)
// → If more than 4 → splits into B-tree nodes
// Why is this better than indirect blocks?
// Indirect blocks: N blocks → O(N) lookup (one pointer per block)
// Extents: N blocks → O(1) extent coverage (contiguous blocks use one record)
// Fragmented files: extent tree may have multiple nodes → still O(log N)
jbd2: Journal
// Write operation path in ext4:
// 1. Write data to disk (data)
// 2. Write metadata changes to journal (metadata)
// 3. Mark journal commit as complete
// 4. Checkpoint: write metadata from journal back to its actual location
//
// On mount:
// Check journal → replay transactions that are committed but not yet checkpointed
// → Restores consistency (fsck is rarely needed)
// data=ordered (default):
// Write data first → then write to journal → data is not visible before metadata
// → File data remains intact after a crash (metadata may be incomplete but won't point to garbage)
// data=writeback:
// Data can be written out of order → faster, but may see stale data after a crash
Delayed Allocation
ext4 delayed allocation:
Write operation → accumulate in page cache first → do not immediately allocate disk blocks
→ On writeback (after accumulating for a few seconds) → allocate large contiguous extents
→ Reduces fragmentation, improves sequential write performance
Costs:
1. write() returning success does not mean disk space is allocated → ENOSPC is delayed until writeback
2. More data loss on crash (dirty pages in page cache, disk blocks not yet allocated)
fallocate can be used to pre-allocate space, avoiding delayed ENOSPC
XFS: Large-Scale Parallelism
Allocation Groups (AG)
XFS divides the filesystem into multiple AGs (Allocation Groups)
Each AG independently manages its own inodes and free space B+tree
→ Multiple threads can allocate in parallel → avoids global locks
→ Outperforms ext4 in high-concurrency scenarios (e.g., multi-threaded databases)
AGs: [AG 0] [AG 1] [AG 2] ... [AG N]
Each AG: has its own superblock copy, inode B+tree, free space B+tree
B+tree Metadata
// Almost all metadata in XFS is organized as B+trees:
// inode B+tree: inode number → inode data
// free space B+tree: offset → free extent
// extent B+tree: file offset → disk extent (per-inode)
//
// Generic B+tree implementation: fs/xfs/libxfs/xfs_btree.c
Reflink and COW
XFS 5.x+ supports reflink (shared data blocks, COW):
cp --reflink=always a b
→ a and b share the same data extent
→ When either is modified → COW → copy the modified block → they become independent
Difference from Btrfs:
XFS reflink is extent-level COW — does not copy the entire file
Btrfs is file-level COW — each snapshot/subvolume writes independently
Btrfs: COW and Data Integrity
COW Architecture
Btrfs COW:
All writes go to new locations → old data is never overwritten
1. Allocate a new extent from free space
2. Write new data
3. Update metadata B-tree to point to the new extent
4. Old extent becomes free
Crash safety:
Because it is COW → old data always remains in place
→ No journal needed (snapshots and reflink are natively supported)
→ Transaction commit = write new root to superblock
Costs:
Fragmentation (frequent COW → logically contiguous data is physically scattered)
Write amplification (small modifications → copy entire extent)
Core Features
Snapshots:
btrfs subvolume snapshot . snapshots/$(date +%Y%m%d)
→ O(1) creation, no data copying
→ COW guarantee: modifying the original subvolume does not affect the snapshot
Subvolumes:
Independent namespaces, can be mounted separately
Similar to ZFS dataset concept
Checksums:
Every data block and metadata block has a checksum (crc32c)
Checked automatically on read → detects bit rot / silent corruption
Works with RAID1 profile: detects corruption → auto-repairs from mirror
Compression:
mount -o compress=zstd → compresses per extent (zlib/lzo/zstd)
B-tree Forest
Btrfs metadata organization:
Multiple B-trees (sharing B-tree code):
Root tree → points to roots of other trees
FS tree → inodes for files/directories (one per subvolume)
Extent tree → extent allocation status
Chunk tree → mapping of chunk groups to physical blocks
Device tree → device information
Csum tree → extent checksums
bcachefs: Next-Generation (6.7+)
Design goals: "Btrfs features + ext4/XFS performance + ZFS data reliability"
Author: Kent Overstreet (original author of bcache)
Core features:
- Primarily COW, optional journal
- Multi-device: different disks can take on different roles
(SSD for foreground/cache, HDD for cold storage)
- Built-in compression (zstd/lz4/gzip) + checksums
- Built-in encryption (per-extent)
- Subvolumes / snapshots
- Stable disk format (merged into mainline 6.7)
Difference from Btrfs:
bcachefs was designed with multi-device tiering in mind from the start
Btrfs RAID is configured at the filesystem level, bcachefs is more flexible
Filesystem Selection
| Feature | ext4 | XFS | Btrfs | bcachefs |
|---|---|---|---|---|
| Max Volume | 1EB | 8EB | 16EB | 8EB |
| Max File | 16TB | 8EB | 16EB | 8EB |
| COW | No | reflink only | Yes | Yes |
| Snapshots | No | No | Yes | Yes |
| Built-in Compression | No | No | Yes | Yes |
| Built-in RAID | No | No | Yes | Yes |
| Checksums | journal only | journal only | metadata+data | metadata+data |
| Suitable Scenarios | General purpose | Large files/databases | NAS | Experimental/multi-device |
References and Further Reading
- Kernel Documentation:
Documentation/filesystems/ext4/,Documentation/filesystems/xfs/,Documentation/filesystems/btrfs.rst - LWN:
- "bcachefs merged" (lwn.net/Articles/947587/)
- "Btrfs: design and implementation" series
- Source Code:
fs/ext4/,fs/xfs/,fs/btrfs/,fs/bcachefs/
Keywords: ext4, extent tree, jbd2, delayed allocation, XFS, allocation group, B+tree, Btrfs, COW, checksum, bcachefs