The server has a fairly complicated directory handling system which we describe here.
A directory is identified by a vnode, and the vnode's data is
stored in a VnodeDiskObject (cvnode.h). The
type
of
the vnode will be directory and the
inodeNumber
will
be an RVM pointer to a
DirInode
. The dir inode contains an
array of page addresses and a reference count to identify the copy
on write references to the directory.
When the pages are placed in a contiguous buffer, the directory
has the standard structure described in
codadir.h
.
A key difference between server and client handling of directories is that there can be more than a single vnode referencing the same directory inode. In the client only a single fso can point to a dir header. Generally the vnodes referencing the directory inode will lie in different volumes, one being a read only clone of another volume. As a result the directory data is an object which needs to be treated independently of the vnode. For this we use a cache of DirHandles.
The interface to the cache is extremely simple:
DC_HashInit
initializes the hash table.
DC_Get
takes as argument a pointer to a DirInode and
enters it in the cache if it wasn't in yet, returning the pointer
to the
DirHandle
. The cache entry has a reference count
which indicates how many VM vnodes are referencing the directory
inode. The in-core copy of the vnode will have its
DirHandle
field set to the result returned by DC_Get. When
the directory data for a Vnode needs to be available, DC_Get is
called with argument
vnode-
>
disk.inode.
Previously
this was achieved by calling SetDirHandle.
At this point in time a VM copy of the directory data is available for manipulation by the fileserver. The routines DH_Lookup, DH_Delete, DH_Create etc. are available to search and modify the VM copy of the directory. Such changes obtain a write lock on the DirHandle since the changes will be visible to other threads accessing the directory.