NFSv4 client: three quarter term report

Blog post by paweł_dziepak on Mon, 2012-08-06 22:09

I’ve recently been working on caching in NFSv4 client. It was essential in order to allow the client to be comfortably used. I can gladly say that the traffic generated by NFS client has been greatly reduced, thanks to metadata, directory, lookup and file caching. I’ve also implemented support for open delegations which, though not always available, allow the client to perform virtually all file operations without immediate server participation.

Undoubtedly, the easiest is metadata caching. Node attributes and access privileged, once got from the server are considered valid for certain amount of time. When the client needs them after they expire another request to the server is issued. Very simple, but also allows to greatly reduce traffic generated by NFS client.

A bit more complicated is directory caching. It heavily relies on change attribute, which allows to check whether a directory entries has been modified between two NFS operations. Using such information the client gets a consistent directory snapshot. Then, periodically the client checks whether current value of change attribute was modified, if yes the snapshot is considered no longer valid.

In order not to invalidate cache by its own requests, as a result of each directory modifying operation the client is provided change attribute before and after that request. If "before" value is the same as change value at which the snapshot was received the client can update the snapshot and consider it still valid. Otherwise, it needs to be marked as invalid.

File cache is implemented in more or less similar way than in local file systems. The only difference is that before an open request is issued the client revalidates cache (using change attribute to check whether file was modified) and when a file is closed all changes are sent to server and committed, forcing server to write it on stable storage.

NFSv4 client also supports open delegations, which are very similar to readers writer locks. When the server decides to grant client a read delegation, the client is allowed to assume that no one modifies that file. Consequently, when a write delegation is granted no one else reads or modifies the file. This allows to skip some file and metadata cache revalidations as well as syncing and committing after file is close.

Server needs a way to recall an open delegation. In order to do so, RPC callbacks are used. The client sends server its address, port and RPC program number. Then, if a delegation needs to be recalled, for example because one client holds a read delegation and another client wants to write to file, server issues a CB_RECALL request to the delegation owner. Upon receiving such request the client sends all modified data, commits it and returns a delegation.

Since caching is done and ready, the only major things left to do are node monitoring (which will be quite straightforward, because of the already implemented directory cache) and support for extended attributes. Apart from that, the code needs some other minor changes and style fixes. Moreover I also want to make the client to be more configurable.