ยง50.4โ€“50.5AFS Version 2: Callbacks, File Identifiers, and Cache Consistency

Part III OSTEP pp. 642โ€“645 ยท ~6 min read

  • callback
  • file identifier
  • last writer wins

The two scale problems demanded a new protocol. AFSv2โ€™s answer is two ideas: a promise mechanism (callbacks) and a compact file name (the FID).

50.4 AFS Version 2

The big idea is the callback : a promise from the server to tell the client whenever a file it is caching gets modified. The client no longer polls (โ€œhas this changed?โ€); it just assumes its cache is valid until the server says otherwise โ€” exactly the shift from polling to interrupts. That alone kills the TestAuth flood.

The second idea is the file identifier (FID), AFSโ€™s answer to the NFS file handle, so the client (not the server) walks the pathname one component at a time:

file identifier (FID) โ€” AFS's file handlevolume idvol = 7file idfile = 42uniquifieruniq = 3reuse guard (after delete)
An FID = volume id + file id + uniquifier. The uniquifier lets IDs be reused safely after a delete (like NFSโ€™s generation number).

Putting both together, watch a file being read โ€” and then re-read almost for free:

Figure 50.2: reading /home/remzi/notes.txt with callbacks. The first open costs several Fetches but sets up callbacks โ€” so re-opens are entirely local.
Client (C1)
Server (Vice)
First open โ€” walk the path, set callbacks
read / close โ€” local
Re-open โ€” the payoff
step 1 / 10 ยท time flows downward

The client walks the path one component at a time, using FIDs.

The first open() of /home/remzi/notes.txt costs several Fetches, but it establishes callbacks on every directory and the file โ€” so later accesses are entirely local, behaving just like a local disk file system. That is exactly the scalability AFS was after.

Aside: Cache Consistency Is Not a Panacea

The baseline consistency a distributed FS provides isnโ€™t enough for everything. If multiple clients do real concurrent updates โ€” say, checking code in and out of a repository โ€” you must use explicit file-level locking; donโ€™t expect the file system alone to sort out conflicts. This baseline is for casual use (log in elsewhere, see a reasonable version of your files).

50.5 Cache Consistency

Recall NFSโ€™s two worries: update visibility (when does the server get the new version?) and the stale cache (how long until others see it?). Thanks to callbacks and whole-file caching, AFSโ€™s answer is refreshingly simple. Between different machines, both happen at the same instant โ€” when the writer calls close():

AFS cross-machine consistency: updates become visible and other caches are invalidated at the SAME moment โ€” when the writer closes the file.
Client 1F[v1]Client 2โ€”Server (Vice)F[v1]callback: validC1 trusts its cache โ€” no polling

1The callback promise

Client 1 opens F and caches it. The server records a callback for C1 on F โ€” a promise to tell C1 if F ever changes. C1 now trusts its cache with no further checks.

step 1 / 5

Thereโ€™s one deliberate exception: between processes on the same machine, writes are immediately visible (normal UNIX semantics) โ€” you donโ€™t wait for a close(). Only when you move to a different machine do you see the close-based model. And when two machines race to modify one file, AFSโ€™s whole-file Store gives last writer wins (really last closer wins): the surviving file is entirely one clientโ€™s or the otherโ€™s โ€” a big contrast with NFS, whose block-by-block flushes can leave a nonsensical mixture of two writersโ€™ data.

Check yourself: callbacks and AFS cache consistency

1.What is a callback in AFSv2, and what problem does it solve?

2.Which analogy best captures the shift callbacks represent?

3.What is an AFS file identifier (FID), and why the 'uniquifier'?

4.Between processes on DIFFERENT machines, when does AFS make an update visible and invalidate other caches?

5.How does AFS treat writes between processes on the SAME machine?

6.If processes on two different machines modify the same file concurrently, what does AFS do?

6 questions