[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.
 |