Coda File System

Next Previous Contents

2. Interfaces

Venus and Vice will access directories through the directory handle api. A directory handle facilitates: - locking of directories - managing rvm and non rvm copies of the data

2.1 DirHandle API

Directory handles are opaque but have a simple internal structure:

struct DirHandle {
    lock           dh_lock;
    PDirHeader     dh_vmdata;
    PDirHeader     dh_rvmdata;
    int            dh_refcount;
};

void DH_LockW(PDirHandle);

Lock the direcotry for writing

void DH_LockR(PDirHandle);

void DH_UnLockW(PDirHandle);

release a write lock

void DH_UnLockR(PDirHandle);

release a read lock

void DH_Init(PDirHandle dh);

initializes the lock in a directory handle.

PDirHandle DH_New(int in_rvm, PDirHeader vmdata, PDirHeader rvmdata);

Instantiate a new directory handle in in VM or RVM and attach directory header pointers to the fields. This routine is probably not useful to Venus and Vice since DirHandle structures are embedded in other structures.

int DH_Length(PDirHandle);

return the length of the directory in bytes. This will always be a multiple of the DIR_PAGESIZE (2048 bytes)

int DH_Create (PDirHandle dh, char *entry, struct DirFid *fid);

Lookup an entry in the directory dh and fill in the fid. This call returns 0 upon success.

int DH_Delete(PDirHandle dh, char *entry);

Remove entry from dh. Return 0 upon success.

void DH_Free(PDirhandle dh, int in_rvm);

Free the data pointed toby (r)vm data field in the handle.

void DH_Alloc(PdirHandle dh, int size, int in_rvm);

Allocate (recoverable) memory of size size in the DirHeader pointers in the dh.

PDirHeader DH_Data(PDirHandle dh);

Return a pointer tothe dirheader in the dirhandle.

void DH_Print(PDirHandle dh);

Print the complete structure of the directory

int DH_MakeDir(PDirHandle dh, PDirFid me, PDirFid parent);

Create a new directory. This call will allocate memory in (r)vm based on the return vlaue of dir_rvm()

int DH_EnumerateDir(PDirHandle dh, int (*hookproc) (struct DirEntry *de, void *hook) , void *hook);

This call williterate through the directory entries and apply hookproc to each, with parameter the dir entry in question and the hook pointer. It will quit when all entries have been processed or when hookproc returns a nonzero value.

The final return value is returned by DH_EnumerateDir.

2.2 DIR api

The DIR api handles the actions on the directory data blobs. These routines are probably only used by the DH api and not elsewhere in the code. This important since it will make switching to a new directory type easy.

The internalhandling of the directory buffers is important. New entries can be created and the routine dir_FindBlobs will locate a sufficient number of blobs. If none are available anymore in the directory the routine dir_AddPage is called. AddPage reallocates a directory buffer which is one pagesize (2048 bytes) larger and then copies the old data into the new one (dir_Extend). Of course this requires a rvm_set_range call when the data is in RVM. After this is done, it adjusts the bitmaps and free counts.

extern int DIR_init(int data_location);

Tells Venus/Vice if directory data is manipulated in RVM or VM. Venus will directly doits transactions on the RVM data (following the pointer in DH). The server manipulates a VM handle and commits the entire blob at commit time.

extern void DIR_Free(struct DirHeader *, int);

extern int DirHash (char *);

Hash value of the name -- could probably be static.

extern int DirToNetBuf(long *, char *, int, int *);

This routine is probably going to be obsolete.

int DIR_MakeDir(struct DirHeader **dir, struct DirFid *me, struct DirFid *parent

Make a new directory with "." and ".." entries as indicated by me and papa.

int DIR_LookupByFid (PDirHeader dhp, char *name, struct DirFid *fid);

The normal important lookup of a name in a directory.

int DIR_EnumberateDir(struct DirHeader *dhp,

int (*hookproc) (struct DirEntry *de, void *hook), void *hook);

Enumerate untilhookproc returns non-null. Return final return value of hookproc.

int DIR_Create(struct DirHeader **dh, char *entry, struct DirFid *fid);

Create a directory entry

int DIR_Length(struct DirHeader *dir);

Length of the directory

int DIR_Delete(struct DirHeader *dir, char *entry);

delete an entry

void DIR_PrintChain(PDirHeader dir, int chain);

print out a hash chain in a directory

int DIR_Convert (PDirHeader dir, char *file);

Convert a directory to Venus BSD format for parsing by the kernel.

sect2 > static int dir_NameBlobs (char *name)

How many blobs are needed for this name?

static int dir_FindBlobs (struct DirHeader **dh, int nblobs

Find a bunch of contiguous entries; at least nblobs in a row.

static int dir_AddPage (struct DirHeader **dh)

Add a page to a directory. This routine has two components. It calls dir_Extend and when the new buffer is made available adjusts the bitmaps, freecounts, etc.

static struct DirHeader *dir_Extend(struct DirHeader *olddir, int in_rvm)

This is the routine which allocates a new buffer (exactly one page larger than the former size of the directory) and frees the previous buffer. Of ocurse it uses a transaction in RVM if this is where data is held.

static struct PageHeader *dir_Page(struct DirHeader *dirh, int page)

Return the PageHeader for the page page in the directory.

static void dir_Freeblobs(struct DirHeader *dhp, register int firstblob, int nblobs)

This is called delete. It makes a group of blobs available again for re-allocation to new entries.

2.3 FID api

There are a variety of fid supporting routines needed in the dir package. The primary

1. ViceFids in use by Venus and Vice are structures containing more information (such as cell and volume information) than fids stored in Coda directories which only contain a vnode and uniquifier.

2. Directories are stored on disk in network order. This means that conversion to host order is appropriate and needs a few supporting routines.

void FID_VFid2DFid(struct ViceFid *vf, struct DirFid *df);

Copy a ViceFid's vnode and unique fields into a directory fid.

void FID_DFiD2VFid(struct DirFid *df, struct ViceFid *vf);

Copy a directory Fid's vnode and unique field into a ViceFid.

void FID_CpyVol (struct ViceFid *taget, struct ViceFid *source);

void FID_Int2DFid (struct DirFid *fid, int vnode, int unique);

Load integers into a fid

void FID_NFid2Int (struct DirNFid *fid, long *vnode, long *unique);

Take vnode and unique out of a directory network fid.

void FID_PrintFid(struct DirFid *fid);

Print a fid

char *FID_s(struct ViceFid *fid);

char *FID_s2(struct ViceFid *fid);

Give a printed version of the fid in a string (statically allocated). Allows for ....

static void fid_Fid2NFid (struct DirFid *fid, struct DirNFid *nfid)

Convert fid to network order

static void fid_NFid2Fid (struct DirNFid *nfid, struct DirFid *fid)

Convert fid to host order

static int fid_FidEqNFid(struct DirFid *fid, struct DirFid *nfid)

Is a network fid equal to a fid?

2.4 Directory Inode API

PDirHeader DI_DiToDh(PDirInode pdi)

Copy the pages in a directory inode to a contiguous area in VM for which memory is malloced. The directory header (i.e. the first page of this data in VM) is returned.

DI_DhToDi(PDirHandle pdh, PDirInode pdi)

Store the pages found in a VM area in RVM. This involves setting ranges and potentially allocating new pages in persistent storage for the object.

DI_Inc(PDirInode)

Increase the reference count to the directory (after a clone for example) in persistent storage.

DI_Dec(PDirInode)

Decrease the RVM refcount on the directory. Remove the directory when this falls to 0.

DI_Count(PDirInode )

Returns the reference count on a directory.

DIPages(PDirInode )

Return the number of pages in the directory.

void *DI_Page(PDirInode pdi, int page)

Return a pointer to a page.

void DI_Copy(PDirInode oldinode, PDirInode *newinode)

Make a copy of a directory inode and the pages. Needed by copy on write.

2.5 Directory Handle Cache API

void DC_HashInit()

Set up the DH hashtable.

void DC_Put(PDirHandle dh)

Decrease the refcount on a hashed directory handle. Remove it when it falls to 0.

struct DirHandle *DC_Get(PDirInode pdi)

Increase the reference count on a cached directory handle or fetch the handle and the data from RVM if not hashed yet.


Next Previous Contents