(AFS development} The initial design of AFS was based around the client server paradigm. However, unlike (at least the original NFS), the system addressed <#2422#> scaling<#2422#> as a base requirement. The goal as to maximise the number of clients that could be served from one machine. To this end, the clients cached whole files, so that a series of passes through the file only resulted in a single access. Even a single pass over the file (a very common pattern of access for example on DOS and Unix systems) could take advantage of streamed requests from the client to the server to fill the cache, which can scale to long haul networks (with a lartge bandwidth/delay product) better than the stop-and-wait performance of an RPC per block of a file. The problem with whole file caching is that it increases the probability of concurrent accesses to a file creating an inconsistent view at the server. In fact, concurrent accesses to write files is rare in many environments, but in some (e.g. workgroup environments) do have many writers of a given file. Hence we need a mechanism for maintaining consistency, either at the server, or to inform clients that their cache is invalid. There are two points on a spectrum of design for how todo this: one extreme is that we are <#2423#> optimistic<#2423#> and the server informs clients in the hopefully `rare' event of intereing writes; the other extreme is that clients check each time they try to carry out any action. The first modification to the AFS (going from AFS 1 to AFS 2), was an optimisation of the cache consistency in two ways: firsly, the servers had an RPC <#2424#> callback<#2424#> to clients to carry out cache invalidation. This elimates the cache validation traffic that was present in the pessimistic AFS 1 (directories are still written through to the server because directory integrity is vital, and the costs are low for this); secondly, the internal implementation of the client and server was enhanced to include <#2425#> threads<#2425#>, which makes handling callbacks more straghtforward. Notice that the decision to move from cache validation to cache invalidation is based on a move in the view of the likelihood of incoherence being pessimistic to optimistic. This is based in actual mesasurements of typical behaviour (i.e. it is an engineering viewpoint change, in ODP modelling terms). The next phase of development of AFS (from AFS 2 to AFS 3) was to deal with another step in scaling. To achieve this, a hierarchy of systems is introduced, called administrative cells. A cell contains a set of clients, servers, users and system adminsitrators, and is also the unit of security management. To work between cells, as well as providing internal security, authentication servers are used. The overall system provides access control lists for protecting files, and groups for aggregating users' permissions. This set of enhancements are possible almost as a layer on top of the previous version of AFS. A refinement of the whole file caching was introduced based (again) on performance analysis of actual usage. This lead to a compromise whereby clients can cache files from servers in 64Kbyte chunks rather than the whole file. This accomodates many typical files (e.g. documents) while also reconginizing that client machines may not have (effectively) infinite local disk store. It can also help with the startup performance (latency) for initial file access, although concurrency in the client code could also help this by allowing early completion of a call to open a file and permitting the client to start reading the file before it has all arrived. The last phase in the evolution of AFS has been to accomodate `disconnected' operation. Many users are starting to use workstations that are wireless. Laptop PCs and PDAs should be able to use AFS, and continue to let a client work on a file even when network access to the server is no longer available, restoring cache consistency when the network is reconnected. This can also support access in less relaible networks. The Coda file system is an extension of AFS 2 (and not 3) to provide two main functions: Server replication permits operations to continue in the even of a link outage; disconnected operation is provided by introducing a new notion of a directory of files that a mobile client may wish to carry around. Replication in Coda is provided through a simple model that a client reads data from a preferred server, but writes data back to all servers. The fact that this is client driven again takes load (and complexity) away from the servers. The many-update protocol uses a two-phase scheme. The first phase attempts to write the data optimistically to all the servers. In the second phase, which operates asynchronously, the client carries out any consistency check by updating version information at the servers. A neat optimisation is that the second phase of the update protocol can be piggybacked on requests to read (or write) new files. Disconencted operation is based on profiling the set of files that a user wishes to <#2426#> hoard<#2426#>, on their laptop. The client access code switches from normal server access to accessing the local copy as the client machine loses conenctivity. When server access is regained, the client goes through a re-integration phase to update the server(s). At this stage, a similar conflict resolution to that employed for partial write fails above might be used.