Source: Operating Systems: Three Easy Pieces (OSTEP) — Chapter 49, Arpaci-Dusseau & Arpaci-Dusseau
Sun’s Network File System (NFS)
Clients talk to a file server that owns the disks. Why not only local disks?
- Sharing — same namespace from any client
- Central admin — backup a few servers, not every laptop
- Security — servers in a locked room
Crux: how do you build a distributed file system? What goes wrong?
Architecture
Apps call the normal POSIX API (open, read, …). The client-side file system turns those into protocol messages; the file server serves them (disk or server cache). Transparent access: same API, (hopefully) similar behavior, remote data.
Sun published an open protocol (message formats) so many vendors could interoperate — a big reason NFS won [S86].
Goal: fast server crash recovery → statelessness
When the server is down, every client is unhappy. NFSv2’s answer: a stateless protocol — the server does not remember open files, cursors, or which clients cache what. Each request carries all information needed to complete.
A stateful open→fd shared with the server is distributed state [O91]: server crash forgets fds; client crash leaves server opens orphaned. Recovery gets messy. Stateless: reboot the server; clients retry.
File handles
FH = (volume ID, inode #, generation #). Generation bumps when an inode is reused so stale handles cannot hit the wrong file.
| Call (sketch) | Client sends | Server returns |
|---|---|---|
| LOOKUP | dir FH + name | FH + attributes |
| READ | FH + offset + count | data + attributes |
| WRITE | FH + offset + count + data | attributes |
| GETATTR | FH | attributes (incl. mtime) |
open("/foo") → LOOKUP; successive read(fd,…) use the client’s fd→FH map and local offset. close is local — no server message.
Rank the sequence
1 / 1Order what happens when a client calls open("/foo") then read(fd, …) twice, then close(fd) (top = first).
OrderDrag the handle to rearrange — top should be first.
- 1open("/foo") triggers a LOOKUP, returning a file handle (FH)
- 2Second READ uses the fd→FH map and the new local offset — no LOOKUP needed
- 3First READ sends FH + offset + count to the server and advances the local offset
- 4close(fd) happens purely locally — no message is sent to the server
Drag items into the correct order (or use ↑↓), then check.
Idempotent retry
Timeouts: lost request, server down, or lost reply. NFSv2 treats them the same — resend.
Idempotent = doing it N times ≡ once. READ/LOOKUP yes; WRITE yes if it includes absolute offset + data. MKDIR is awkward (success + lost reply → retry “fails”). Voltaire’s Law: perfect is the enemy of the good.
Client caching and consistency
Caching data (and buffering writes) is mandatory for speed — and creates the cache consistency problem:
- Update visibility — C2’s dirty
F[v2]still only in C2’s RAM - Stale cache — server has
F[v2]but C1 still holdsF[v1]
NFSv2 engineering:
- Flush-on-close (close-to-open): close forces dirty pages to the server so a later open elsewhere can see updates
- Validate before use: GETATTR; newer server mtime → invalidate cache
- Attribute cache (~few seconds) stops GETATTR storms — at the cost of fuzzy “which version?” semantics
Rank the sequence
1 / 1Order the close-to-open consistency flow when C1 writes a file and C2 later reads it (top = first).
OrderDrag the handle to rearrange — top should be first.
- 1C1 closes the file, which flushes the dirty pages to the server (flush-on-close)
- 2C1 writes to the file, dirtying pages only in C1's local RAM
- 3C2 re-fetches the data from the server instead of using its old cached copy
- 4C2's GETATTR on open sees the newer server mtime and invalidates its stale cache
Drag items into the correct order (or use ↑↓), then check.
Server write buffering
The server must not ack WRITE success until data is on stable storage. Otherwise a crash after a buffered “success” can leave holes (client thinks a,b,c wrote; disk has a, old, c). Fast NFS appliances use battery-backed memory + write-optimized FS layouts [HLM94].
VFS/vnode [K86]: Sun’s pluggable FS interface so NFS could sit beside local FS — still everywhere.
Interactive
Try: why DFS · stateless FH · idempotent retry · cache consistency · server durable WRITE.
Check your understanding
Sun NFS
1 / 6NFSv2’s main protocol design goal emphasized here is…
Pick an answer to see if you are right.
Coding challenges
Homework lab: NFS trace analysis
Use the OSTEP dist-nfs homework (Ellard/Seltzer-style traces [ES03]).
Homework: NFS traces
0/3 startedSummary
| Idea | Takeaway |
|---|---|
| Stateless | Fast crash recovery; FH + offsets in every call |
| Idempotent retry | One client strategy for loss and reboot |
| Client cache | Speed vs consistency (close-to-open + attr cache) |
| Stable WRITE | Server durability before success |
| VFS | Pluggable local + NFS side by side |
Previous: Distributed Systems
Next: Andrew File System — callbacks, whole-file cache, scale.
Further Reading
- Remzi & Andrea Arpaci-Dusseau — Operating Systems: Three Easy Pieces Ch. 49
- OSTEP NFS PDF
- OSTEP dist-nfs homework
- Sandberg NFS [S86]; Callaghan NFS Illustrated [C00]; Kleiman VFS [K86]