Β§40.7–40.8Caching, Write Buffering, and Summary

Part III OSTEP pp. 506–508 Β· ~5 min read

  • write buffering

The last section left us with a crux: even simple operations trigger many scattered I/Os. The first line of defense is memory.

40.7 Caching and Buffering

Caching reads. Without a cache, every open costs at least two reads per directory level β€” a path like /1/2/…/100/file.txt would trigger hundreds of reads. So file systems cache popular blocks in DRAM. Early systems used a fixed-size cache (~10% of memory, LRU-managed); modern systems instead fold file-system blocks and virtual-memory pages into one unified page cache , partitioned dynamically:

Static: fixed ~10% FS cacheFSvirtual memoryidle FS cache β†’ wastedDynamic: unified page cache (VM + FS pages)file-system pagesVM pagesboundary shifts on demand β€” no waste

Tip: Understand Static vs Dynamic Partitioning

When splitting a resource among users, you can divide it once (static) or flex the division over time (dynamic). Static is predictable and simple but can waste idle capacity; dynamic uses resources better but is more complex. Neither is always best β€” match the approach to the problem.

Static vs dynamic partitioning of memory between the file-system cache and virtual memory.
static partitioningdynamic partitioning
Howfix the split once (e.g. 10% to the FS cache at boot)shift the split over time as needs change
Upsidepredictable performance; simple to buildbetter utilization
Downsidewasteful β€” idle FS-cache pages can't be repurposedmore complex; a user's reclaimed memory may be slow to get back
Dotted-underlined cells have explanations β€” click one.

Buffering writes. Caching filters reads (a hit avoids the disk entirely), but writes must eventually reach disk to be durable β€” a cache can’t filter them away. What it can do is delay them: write buffering holds writes in memory for 5–30 seconds before committing:

Write buffering delays writes in memory (5–30 s), then commits them β€” trading a little durability for a lot of performance.
DRAM bufferwrite inode bitmapwrite inode bitmap (again)create foo β†’ then delete foodisknot yet written⚑write() returns fast Β· a crash here loses it

1Writes land in the buffer, not on disk

A write() returns as soon as the data sits in the in-memory buffer; the disk write happens later. The application sees fast writes β€” but the data is not yet durable.

step 1 / 3

Tip: The Durability / Performance Trade-off

Buffering makes writes feel instant and enables batching, scheduling, and cancellation β€” but buffered writes are lost if the machine crashes first. Applications that can’t tolerate this (databases) opt out by calling fsync(), using direct I/O, or writing to the raw disk. Match the guarantee to what the data is worth: a lost browser thumbnail is fine; a lost bank transaction is not.

40.8 Summary

We’ve built the basic machinery of a file system: inodes hold each file’s metadata and block pointers; directories are just files mapping names to inode numbers; bitmaps track which inodes and blocks are free; and the access paths show how opens, reads, and writes turn into scattered disk I/Os β€” which caching and write buffering then work to reduce.

The beauty of file-system design is its freedom: every structure and policy here can be changed. The chapters ahead exploit exactly that β€” FFS adds a locality policy, journaling makes the 5-I/O allocating write crash-safe, and LFS turns all those scattered writes into one big sequential stream.

Check yourself: caching and write buffering

1.Why do file systems cache blocks in memory?

2.What is the modern approach to the file-system cache?

3.Why doesn't caching reduce WRITE traffic the way it reduces read traffic?

4.Which are genuine benefits of delaying writes (write buffering)?

5.What is the durability/performance trade-off of write buffering?

6.How can an application that can't tolerate buffering loss (e.g. a database) force durability?

6 questions