Chapter 10: Filesystems and Mount Options
Chapter 10: Filesystems and Mount Options
The filesystem is responsible for structuring raw block storage into hierarchical directories and files, managing free space allocation, maintaining metadata consistency, and coordinating concurrent access. Choosing the appropriate filesystem and configuring mount options can alter I/O throughput and latency by more than 40%.
This chapter compares the internal architectures of ext4, XFS, and btrfs, analyzes journaling costs, evaluates critical mount flags, and details filesystem caching mechanisms.
ext4: Journaling, Allocation and Performance
The Fourth Extended Filesystem (ext4) is the default general-purpose filesystem for many Linux distributions:
- Block Groups and Extents: Physical space is divided into Block Groups. ext4 replaced legacy indirect block pointers with contiguous Extents (mapping up to 128MB of contiguous physical blocks per extent record), significantly reducing metadata overhead.
- Delayed Allocation (
delalloc): ext4 delays allocating physical blocks on disk until data is actually written out from the Page Cache by writeback threads. This allows the allocator to group adjacent writes into large contiguous extents, preventing fragmentation. - Directory Indexing (
dir_index): Uses hashed B-trees (HTrees) to accelerate lookups in directories containing hundreds of thousands of files.
XFS: Design Principles and Scalability
XFS was engineered by Silicon Graphics (SGI) for extreme scalability, massive storage capacity, and highly parallel workloads:
- Allocation Groups (AGs): XFS divides the storage space into multiple completely independent Allocation Groups (typically 4 to 32 AGs). Each AG possesses its own free-space B+trees and inode allocation maps.
- Parallel Allocation: Unlike ext4, which can suffer lock contention when hundreds of threads allocate blocks concurrently, XFS allows concurrent threads to allocate space across separate Allocation Groups in parallel without lock collisions.
- Dynamic Inodes: Inodes are allocated dynamically across AGs as needed, avoiding the fixed inode count limitations of traditional filesystems.
[!TIP] For high-concurrency database workloads (PostgreSQL, MySQL/InnoDB) and multi-terabyte flash arrays, XFS is universally preferred over ext4 due to its lockless Allocation Group architecture.
btrfs and Copy-on-Write Semantics
Btrfs (B-tree Filesystem) uses a Copy-on-Write (CoW) architecture combined with integrated volume management:
- CoW Mechanics: Existing data blocks are never overwritten in place. When a block is modified, the new data is written to a completely free block, and metadata pointers are updated up the root tree.
- Snapshots and Checksums: Provides near-instantaneous subvolume snapshots and data/metadata CRC32c/XXH64 checksumming for silent data corruption detection.
- Performance Trade-offs: CoW introduces severe fragmentation when handling random write-in-place workloads (e.g., database files or VM disk images). While snapshots and checksums provide strong integrity guarantees, btrfs typically exhibits lower peak random write throughput compared to XFS.
Filesystem Journaling and Write Performance
To maintain filesystem consistency across sudden crashes and power losses, filesystems maintain an append-only circular log called a Journal:
┌────────────────────────────────────────────────────────────────────────┐
│ JOURNALING MODES (EXT4) │
│ │
│ data=journal │
│ ├─ Both metadata AND file data written to journal first │
│ └─ Safest, but cuts write throughput by ~50% (double write penalty) │
│ │
│ data=ordered (Default) │
│ ├─ File data written to main storage first │
│ └─ Metadata written to journal before committing transaction │
│ │
│ data=writeback │
│ ├─ Only metadata is journaled; file data written whenever │
│ └─ Highest throughput; risk of stale data leaks on sudden crash │
└────────────────────────────────────────────────────────────────────────┘
The Cost of fsync()
When an application calls fsync() or fdatasync(): 1. The kernel flushes all dirty Page Cache pages for the file to disk. 2. The filesystem flushes the journal transaction to storage. 3. The block layer issues a hardware Cache Flush Barrier to the disk controller, forcing the drive to dump its internal volatile write cache.
Frequent fsync() calls in synchronous loops throttle throughput to the physical disk flush latency (~500\(\mu\)s–5ms per call).
Mount Options: Performance Implications
Mount options instruct the VFS and filesystem drivers how to treat metadata updates and caching:
| Mount Flag | Default | Performance Optimization | Risk / Trade-off |
|---|---|---|---|
noatime |
relatime |
Eliminates disk writes whenever a file is read | None for 99.9% of servers (breaks legacy mutt mail). Essential for performance. |
nodiratime |
Enabled | Stops updating directory access times on reads | Subsumed by noatime. |
barrier=0 / nobarrier |
barrier=1 |
Disables hardware write cache flush commands | Extreme data loss risk: silent filesystem corruption on power loss unless protected by reliable BBU. |
commit=N |
commit=5 |
Extends sync interval for journal commits (e.g. commit=30) |
Batches journal updates; increases window of lost data during crashes to \(N\) seconds. |
discard vs fstrim |
Variable | Continuous sync discard degrades write latency | Replace continuous discard mount flag with periodic weekly fstrim.timer. |
# Recommended production mount entry for high-performance XFS on NVMe
/dev/nvme0n1p1 /data xfs defaults,noatime,allocsize=64M 0 0Filesystem-Level Caching and Coherency
- Dentry Cache (dcache): Caches directory entries (
struct dentry), mapping path strings to inodes in memory. Eliminates disk lookups for path resolution. - Inode Cache (icache): Keeps active filesystem inode metadata in memory.
- Direct I/O (
O_DIRECT): Bypasses both the Page Cache and filesystem read-ahead, issuing DMA transfers directly between userspace memory buffers and the storage controller. Used by databases (Oracle, ScyllaDB, PostgreSQL with direct I/O) to manage their own caching algorithms without double-buffering in the Page Cache.