[enfs-devel] NFS V3 implementation
Brought to you by:
tramm
From: Lee W. <le...@sa...> - 2001-11-21 17:30:20
|
All, I'm having some troubles deciding just how to do the NFS V3 implementation. Problem is, I've started down a path that is proving untenable. What I've done so far is to reorganize the NFS V2 into client and server directories, with subdirectories, by version. Like this: -> clnt -> v2 -> v3 ... -> nfs -> srvr -> v2 -> v3 Then, I lifted the infrastructure code (cached attributes, nfs_findi, etc) out of the V2 code and dropped it into the "clnt" and "srvr" directories. Finally, I altered the nfs_inode to try to account for supporting the different file handles and attribute records. What, I've *really* done is to make a base-class NFS inode, with two sub-classes; one for each version. I cheated though by just using a V3 file handle (it'll record both V2 and V3 handles with equal ease) and replaced the V2 attributes with a union of the two kinds of attributes. The idea is that the VOP_ routines know which kind of inode they are dealing with and can choose the appropriate union member correctly, without further knowledge. i.e., the "base-class" record definition wasn't really, itself, sub-classed. This all seemed like a good idea at the time. I've made good progress on the V3 implementation but, now, I'm trying to implement VOP_READDIR. The V3 READDIR3 and READDIRPLUS3 calls need a verifier cookie when using a non-zero directory offset. i.e., if the entire directory can't be enumerated in one call, the continuation requires a verifier so that the server can make a determination about the validity of the given offset. These cookies are returned by the readdir and readdir+ calls. I need to store them in the inode record so that I can use them in these potential continuations. The natural thing, based on what I've already done, is to just change the union in the nfs-inode from: ... union { fattr2 nfsi_attrs2; fattr3 nfsi_attrs3; } nfsi_attrs; ... to: ... union { fattr2 nfsi_attrs2; struct { fattr3 nfsi_attrs3; char nfsi_dircookie[NFS3_COOKIEVERFSIZE]; } nfsi_attrs3; } nfsi_attrs; ... While the V2 code would be unaffected by this new change, the V3 code is not so lucky. Everything in the V3 code that needs to set the attributes now needs to know whether it's working with a directory or some other kind of object, since we need to invalidate these cookies independent of the attributes. Like, when we do a rename (target parent != source), create, mkdir, unlink for instance. This would be OK, I suppose, but the V3 implementation balloons and is cumbersome. It occurs to me that I've made a fundamental mistake in the implementation design. I've shoved all the subclass-only info up into the base record. However, to do otherwise, I would have to either alter (or provide anew for each version) the new-inode function to account for different sizes/kinds of info or inform the generic, existing new-inode function a pointer to subclass data. Then, there's still the problem of whether I'm dealing with a directory or not. How does the super find it's base record info? It goes on... Worse, all this is going to be worse with NFS V4. In V4, there is now state kept. This state will have to be stored in the sub-class record. To just provide the super with indirect function pointers is attractive but could be more and more problematic. In short, I don't like anything I've come up with much. Some helpful thoughts would be appreciated. |