/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
afs_int32 page;
afs_int32 accesstime;
struct buffer *hashNext;
- char *data;
+ void *data;
char lockers;
char dirty;
char hashIndex;
struct Lock lock;
- } **Buffers;
+} **Buffers;
-char *BufferData;
+void *BufferData;
static struct buffer *phTable[PHSIZE]; /* page hash table */
static struct buffer *LastBuffer;
int DStat (abuffers, acalls, aios)
int *abuffers, *acalls, *aios;
- {*abuffers = nbuffers;
+{
+ *abuffers = nbuffers;
*acalls = calls;
*aios = ios;
return 0;
- }
+ }
int DInit (abuffers)
int abuffers;
- {/* Initialize the venus buffer system. */
+{
+ /* Initialize the venus buffer system. */
register int i, tsize;
register struct buffer *tb;
- register char *tp;
+ register void *tp;
Lock_Init(&afs_bufferLock);
/* Align each element of Buffers on a doubleword boundary */
tsize = (sizeof(struct buffer) + 7) & ~7;
- tp = (char *) malloc(abuffers * tsize);
+ tp = (void *) malloc(abuffers * tsize);
Buffers = (struct buffer **) malloc(abuffers * sizeof(struct buffer *));
- BufferData = (char *) malloc(abuffers * BUFFER_PAGE_SIZE);
+ BufferData = (void *) malloc(abuffers * BUFFER_PAGE_SIZE);
timecounter = 0;
LastBuffer = (struct buffer *)tp;
nbuffers = abuffers;
return 0;
}
-char *DRead(fid,page)
+void *DRead(fid,page)
register afs_int32 *fid;
register int page;
-{ /* Read a page from the disk. */
+{
+ /* Read a page from the disk. */
register struct buffer *tb, *tb2, **bufhead;
ObtainWriteLock(&afs_bufferLock);
#define buf_Front(head,parent,p) {(parent)->hashNext = (p)->hashNext; (p)->hashNext= *(head);*(head)=(p);}
/* this apparently-complicated-looking code is simply an example of
- * a little bit of loop unrolling, and is a standard linked-list
+ * a little bit of loop unrolling, and is a standard linked-list
* traversal trick. It saves a few assignments at the the expense
* of larger code size. This could be simplified by better use of
* macros. With the use of these LRU queues, the old one-cache is
- * probably obsolete.
+ * probably obsolete.
*/
- if ( tb = phTable[pHash(fid)] ) { /* ASSMT HERE */
+ if ( tb = phTable[pHash(fid)] ) { /* ASSMT HERE */
if (bufmatch(tb)) {
ObtainWriteLock(&tb->lock);
tb->lockers++;
return tb->data;
}
else {
- bufhead = &( phTable[pHash(fid)] );
- while (tb2 = tb->hashNext) {
- if (bufmatch(tb2)) {
- buf_Front(bufhead,tb,tb2);
- ObtainWriteLock(&tb2->lock);
- tb2->lockers++;
- ReleaseWriteLock(&afs_bufferLock);
- tb2->accesstime = ++timecounter;
- ReleaseWriteLock(&tb2->lock);
- return tb2->data;
- }
- if (tb = tb2->hashNext) { /* ASSIGNMENT HERE! */
- if (bufmatch(tb)) {
- buf_Front(bufhead,tb2,tb);
- ObtainWriteLock(&tb->lock);
- tb->lockers++;
- ReleaseWriteLock(&afs_bufferLock);
- tb->accesstime = ++timecounter;
- ReleaseWriteLock(&tb->lock);
- return tb->data;
- }
+ bufhead = &( phTable[pHash(fid)] );
+ while (tb2 = tb->hashNext) {
+ if (bufmatch(tb2)) {
+ buf_Front(bufhead,tb,tb2);
+ ObtainWriteLock(&tb2->lock);
+ tb2->lockers++;
+ ReleaseWriteLock(&afs_bufferLock);
+ tb2->accesstime = ++timecounter;
+ ReleaseWriteLock(&tb2->lock);
+ return tb2->data;
+ }
+ if (tb = tb2->hashNext) { /* ASSIGNMENT HERE! */
+ if (bufmatch(tb)) {
+ buf_Front(bufhead,tb2,tb);
+ ObtainWriteLock(&tb->lock);
+ tb->lockers++;
+ ReleaseWriteLock(&afs_bufferLock);
+ tb->accesstime = ++timecounter;
+ ReleaseWriteLock(&tb->lock);
+ return tb->data;
+ }
+ }
+ else break;
}
- else break;
- }
}
- }
+ }
else tb2 = NULL;
/* can't find it */
/* The last thing we looked at was either tb or tb2 (or nothing). That
- * is at least the oldest buffer on one particular hash chain, so it's
+ * is at least the oldest buffer on one particular hash chain, so it's
* a pretty good place to start looking for the truly oldest buffer.
*/
tb = newslot(fid, page, (tb ? tb : tb2));
static FixupBucket(ap)
register struct buffer *ap;
- {register struct buffer **lp, *tp;
+{
+ register struct buffer **lp, *tp;
register int i;
/* first try to get it out of its current hash bucket, in which it might not be */
i = ap->hashIndex;
struct buffer *newslot (afid, apage, lp)
afs_int32 *afid, apage;
- register struct buffer *lp; /* pointer to a fairly-old buffer */
- {/* Find a usable buffer slot */
+ register struct buffer *lp; /* pointer to a fairly-old buffer */
+{
+ /* Find a usable buffer slot */
register afs_int32 i;
afs_int32 lt;
register struct buffer **tbp;
if (lp && (lp->lockers == 0)) {
- lt = lp->accesstime;
+ lt = lp->accesstime;
}
else {
- lp = 0;
- lt = BUFFER_LONG_MAX;
+ lp = 0;
+ lt = BUFFER_LONG_MAX;
}
tbp = Buffers;
for (i=0;i<nbuffers;i++,tbp++) {
- if ((*tbp)->lockers == 0) {
- if ((*tbp)->accesstime < lt) {
- lp = (*tbp);
- lt = (*tbp)->accesstime;
+ if ((*tbp)->lockers == 0) {
+ if ((*tbp)->accesstime < lt) {
+ lp = (*tbp);
+ lt = (*tbp)->accesstime;
+ }
}
- }
}
/* There are no unlocked buffers */
if (lp == 0) {
- if (lt < 0)
- Die("accesstime counter wrapped");
- else
- Die ("all buffers locked");
+ if (lt < 0)
+ Die("accesstime counter wrapped");
+ else
+ Die ("all buffers locked");
}
/* We do not need to lock the buffer here because it has no lockers
if (lp->dirty) {
if (ReallyWrite(lp->fid,lp->page,lp->data)) Die("writing bogus buffer");
lp->dirty = 0;
- }
+ }
/* Now fill in the header. */
FidZap(lp->fid);
FixupBucket(lp); /* move to the right hash bucket */
return lp;
- }
+}
void
DRelease (bp,flag)
register struct buffer *bp;
int flag;
- {/* Release a buffer, specifying whether or not the buffer has been modified by the locker. */
+{
+ /* Release a buffer, specifying whether or not the buffer has been modified by the locker. */
register int index;
if (!bp) return;
- index = (((char *)bp)-((char *)BufferData))>>LOGPS;
+ index = (((void *)bp)-((void *)BufferData))>>LOGPS;
bp = Buffers[index];
ObtainWriteLock(&bp->lock);
bp->lockers--;
if (flag) bp->dirty=1;
ReleaseWriteLock(&bp->lock);
- }
+}
DVOffset (ap)
register void *ap;
- {/* Return the byte within a file represented by a buffer pointer. */
+{
+ /* Return the byte within a file represented by a buffer pointer. */
register struct buffer *bp;
register int index;
bp=ap;
- index = (((char *)bp) - ((char *)BufferData)) >> LOGPS;
+ index = (((void *)bp) - ((void *)BufferData)) >> LOGPS;
if (index<0 || index >= nbuffers) return -1;
bp = Buffers[index];
- return BUFFER_PAGE_SIZE*bp->page+((char *)ap)-bp->data;
- }
+ return BUFFER_PAGE_SIZE*bp->page+((void *)ap)-bp->data;
+}
DZap (fid)
register afs_int32 *fid;
- {/* Destroy all buffers pertaining to a particular fid. */
+{
+ /* Destroy all buffers pertaining to a particular fid. */
register struct buffer *tb;
ObtainReadLock(&afs_bufferLock);
for(tb=phTable[pHash(fid)]; tb; tb=tb->hashNext)
ReleaseWriteLock(&tb->lock);
}
ReleaseReadLock(&afs_bufferLock);
- }
+}
DFlushVolume (vid)
register afs_int32 vid;
- {/* Flush all data and release all inode handles for a particular volume */
+{
+ /* Flush all data and release all inode handles for a particular volume */
register struct buffer *tb;
register int code, rcode = 0;
ObtainReadLock(&afs_bufferLock);
}
ReleaseReadLock(&afs_bufferLock);
return rcode;
- }
+}
DFlushEntry (fid)
-register afs_int32 *fid;
-{/* Flush pages modified by one entry. */
+ register afs_int32 *fid;
+{
+ /* Flush pages modified by one entry. */
register struct buffer *tb;
int code;
}
DFlush ()
-{/* Flush all the modified buffers. */
+{
+ /* Flush all the modified buffers. */
register int i;
register struct buffer **tbp;
afs_int32 code, rcode;
if ((*tbp)->dirty) {
code = ReallyWrite((*tbp)->fid, (*tbp)->page, (*tbp)->data);
if (!code)
- (*tbp)->dirty = 0; /* Clear the dirty flag */
+ (*tbp)->dirty = 0; /* Clear the dirty flag */
if (code && !rcode) {
rcode = code;
}
return rcode;
}
-char *DNew (fid,page)
- register int page;
- register afs_int32 *fid;
+void *DNew (fid,page)
+ register int page;
+ register afs_int32 *fid;
{
/* Same as read, only do *not* even try to read the page,
* since it probably doesn't exist.
/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
-# include <sys/types.h>
+# include <sys/types.h>
# include <errno.h>
# include "dir.h"
#ifdef AFS_NT40_ENV
struct DirEntry *DNew();
/* Local static prototypes */
-static struct DirEntry *FindItem (char *dir, char *ename,
+static struct DirEntry *FindItem (void *dir, char *ename,
unsigned short **previtem);
return 1+((i+15)>>5);
}
-int Create (char *dir, char *entry, afs_int32 *vfid)
+/* Create an entry in a file. Dir is a file representation, while entry is a string name. */
+
+int Create (void *dir, char *entry, void *voidfid)
{
- /* Create an entry in a file. Dir is a file representation, while entry is a string name. */
+ afs_int32 *vfid = (afs_int32 *) voidfid;
int blobs, firstelt;
register int i;
register struct DirEntry *ep;
/* check name quality */
if (*entry == 0) return EINVAL;
/* First check if file already exists. */
- ep = FindItem(dir,entry,&pp);
+ ep = FindItem(dir, entry, &pp);
if (ep) {
DRelease(ep, 0);
DRelease(pp, 0);
return EEXIST;
}
blobs = NameBlobs(entry); /* number of entries required */
- firstelt = FindBlobs(dir,blobs);
+ firstelt = FindBlobs(dir, blobs);
if (firstelt < 0) return EFBIG; /* directory is full */
/* First, we fill in the directory entry. */
- ep = GetBlob(dir,firstelt);
+ ep = GetBlob(dir, firstelt);
if (ep == 0) return EIO;
ep->flag = FFIRST;
ep->fid.vnode = htonl(vfid[1]);
ep->fid.vunique = htonl(vfid[2]);
- strcpy(ep->name,entry);
+ strcpy(ep->name, entry);
/* Now we just have to thread it on the hash table list. */
dhp = (struct DirHeader *) DRead(dir,0);
if (!dhp) {
return 0;
}
-int Length (char *dir)
+int Length (void *dir)
{
int i,ctr;
struct DirHeader *dhp;
return ctr*AFS_PAGESIZE;
}
-int Delete (char *dir, char *entry)
+int Delete (void *dir, char *entry)
{
/* Delete an entry from a directory, including update of all free entry descriptors. */
int nitems, index;
return 0;
}
-int FindBlobs (char *dir, int nblobs)
+int FindBlobs (void *dir, int nblobs)
{
/* Find a bunch of contiguous entries; at least nblobs in a row. */
register int i, j, k;
return -1;
}
-void AddPage (char *dir, int pageno)
+void AddPage (void *dir, int pageno)
{/* Add a page to a directory. */
register int i;
register struct PageHeader *pp;
DRelease(pp,1);
}
-void FreeBlobs(char *dir, register int firstblob, int nblobs)
+/* Free a whole bunch of directory entries. */
+
+void FreeBlobs(void *dir, register int firstblob, int nblobs)
{
- /* Free a whole bunch of directory entries. */
register int i;
int page;
struct DirHeader *dhp;
if (pp) for (i=0;i<nblobs;i++)
pp->freebitmap[(firstblob+i)>>3] &= ~(1<<((firstblob+i)&7));
DRelease(pp,1);
- }
+}
-int MakeDir (char *dir, afs_int32 *me, afs_int32 *parent)
+/*
+ * Format an empty directory properly. Note that the first 13 entries in a
+ * directory header page are allocated, 1 to the page header, 4 to the
+ * allocation map and 8 to the hash table.
+ */
+int MakeDir (void *dir, afs_int32 *me, afs_int32 *parent)
{
- /* Format an empty directory properly. Note that the first 13 entries in a directory header
- page are allocated, 1 to the page header, 4 to the allocation map and 8 to the hash table. */
register int i;
register struct DirHeader *dhp;
dhp = (struct DirHeader *) DNew(dir,0);
Create(dir,".",me);
Create(dir,"..",parent); /* Virtue is its own .. */
return 0;
- }
+}
-int Lookup (char *dir, char *entry, register afs_int32 *fid)
+/* Look up a file name in directory. */
+
+int Lookup (void *dir, char *entry, void *voidfid)
{
- /* Look up a file name in directory. */
+ afs_int32 *fid = (afs_int32 *) voidfid;
register struct DirEntry *firstitem;
unsigned short *previtem;
return 0;
}
-int LookupOffset (char *dir, char *entry, register afs_int32 *fid, long *offsetp)
+/* Look up a file name in directory. */
+
+int LookupOffset (void *dir, char *entry, void *voidfid, long *offsetp)
{
- /* Look up a file name in directory. */
- register struct DirEntry *firstitem;
- unsigned short *previtem;
-
- firstitem = FindItem(dir,entry,&previtem);
- if (firstitem == 0) return ENOENT;
- DRelease(previtem,0);
- fid[1] = ntohl(firstitem->fid.vnode);
- fid[2] = ntohl(firstitem->fid.vunique);
- if (offsetp)
- *offsetp = DVOffset(firstitem);
- DRelease(firstitem,0);
- return 0;
+ afs_int32 *fid = (afs_int32 *) voidfid;
+ register struct DirEntry *firstitem;
+ unsigned short *previtem;
+
+ firstitem = FindItem(dir,entry,&previtem);
+ if (firstitem == 0) return ENOENT;
+ DRelease(previtem,0);
+ fid[1] = ntohl(firstitem->fid.vnode);
+ fid[2] = ntohl(firstitem->fid.vunique);
+ if (offsetp)
+ *offsetp = DVOffset(firstitem);
+ DRelease(firstitem,0);
+ return 0;
}
-int EnumerateDir (char *dir, int (*hookproc)(), void *hook)
+int EnumerateDir (void *dir, int (*hookproc)(), void *hook)
{
/* Enumerate the contents of a directory. */
register int i;
return 0;
}
-int IsEmpty (char *dir)
+int IsEmpty (void *dir)
{
/* Enumerate the contents of a directory. */
register int i;
return 0;
}
-struct DirEntry *GetBlob (char *dir, afs_int32 blobno)
+struct DirEntry *GetBlob (void *dir, afs_int32 blobno)
{
/* Return a pointer to an entry, given its number. */
struct DirEntry *ep;
return tval;
}
-static struct DirEntry *FindItem (char *dir, char *ename,
+static struct DirEntry *FindItem (void *dir, char *ename,
unsigned short **previtem)
{
/* Find a directory entry, given its name. This entry returns a pointer to a locked buffer, and a pointer to a locked buffer (in previtem) referencing the found item (to aid the delete code). If no entry is found, however, no items are left locked, and a null pointer is returned instead. */
/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
#define FNEXT 2
struct MKFid
- {/* A file identifier. */
- afs_int32 vnode; /* file's vnode slot */
- afs_int32 vunique; /* the slot incarnation number */
- };
+{ /* A file identifier. */
+ afs_int32 vnode; /* file's vnode slot */
+ afs_int32 vunique; /* the slot incarnation number */
+};
struct PageHeader
- {/* A page header entry. */
+{
+ /* A page header entry. */
unsigned short pgcount; /* number of pages, or 0 if old-style */
unsigned short tag; /* 1234 in network byte order */
- char freecount; /* unused, info in dirHeader structure */
+ char freecount; /* unused, info in dirHeader structure */
char freebitmap[EPP/8];
char padding[32-(5+EPP/8)];
- };
+};
struct DirHeader
- {/* A directory header object. */
+{
+ /* A directory header object. */
struct PageHeader header;
- char alloMap[MAXPAGES]; /* one byte per 2K page */
+ char alloMap[MAXPAGES]; /* one byte per 2K page */
unsigned short hashTable[NHASHENT];
- };
+};
struct DirEntry
- {/* A directory entry */
+{
+ /* A directory entry */
char flag;
- char length; /* currently unused */
+ char length; /* currently unused */
unsigned short next;
struct MKFid fid;
char name[16];
- };
+};
struct DirXEntry
- {/* A directory extension entry. */
+{
+ /* A directory extension entry. */
char name[32];
- };
+};
struct DirPage0
- {/* A page in a directory. */
+{
+ /* A page in a directory. */
struct DirHeader header;
struct DirEntry entry[1];
- };
+};
struct DirPage1
- {/* A page in a directory. */
+{
+ /* A page in a directory. */
struct PageHeader header;
struct DirEntry entry[1];
- };
+};
/*
* Note that this declaration is seen in both the kernel code and the
/* Prototypes */
extern int NameBlobs (char *name);
-extern int Create (char *dir, char *entry, afs_int32 *vfid);
-extern int Length (char *dir);
-extern int Delete (char *dir, char *entry);
-extern int FindBlobs (char *dir, int nblobs);
-extern void AddPage (char *dir, int pageno);
-extern void FreeBlobs(char *dir, register int firstblob, int nblobs);
-extern int MakeDir (char *dir, afs_int32 *me, afs_int32 *parent);
-extern int Lookup (char *dir, char *entry, register afs_int32 *fid);
-extern int LookupOffset (char *dir, char *entry, register afs_int32 *fid, long *offsetp);
-extern int EnumerateDir (char *dir, int (*hookproc)(void *dir, char *name, afs_int32 vnode, afs_int32 unique), void *hook);
-extern int IsEmpty (char *dir);
-extern struct DirEntry *GetBlob (char *dir, afs_int32 blobno);
+extern int Create (void *dir, char *entry, void *vfid);
+extern int Length (void *dir);
+extern int Delete (void *dir, char *entry);
+extern int FindBlobs (void *dir, int nblobs);
+extern void AddPage (void *dir, int pageno);
+extern void FreeBlobs(void *dir, register int firstblob, int nblobs);
+extern int MakeDir (void *dir, afs_int32 *me, afs_int32 *parent);
+extern int Lookup (void *dir, char *entry, void *fid);
+extern int LookupOffset (void *dir, char *entry, void *fid, long *offsetp);
+extern int EnumerateDir (void *dir, int (*hookproc)(void *dir, char *name, afs_int32 vnode, afs_int32 unique), void *hook);
+extern int IsEmpty (void *dir);
+extern struct DirEntry *GetBlob (void *dir, afs_int32 blobno);
extern int DirHash (register char *string);
#ifdef KERNEL
extern int afs_dir_NameBlobs (char *name);
-extern int afs_dir_Create (char *dir, char *entry, afs_int32 *vfid);
-extern int afs_dir_Length (char *dir);
-extern int afs_dir_Delete (char *dir, char *entry);
-extern int afs_dir_MakeDir (char *dir, afs_int32 *me, afs_int32 *parent);
-extern int afs_dir_Lookup (char *dir, char *entry, register afs_int32 *fid);
-extern int afs_dir_LookupOffset (char *dir, char *entry, register afs_int32 *fid, long *offsetp);
-extern int afs_dir_EnumerateDir (char *dir, int (*hookproc)(void *dir, char *name, afs_int32 vnode, afs_int32 unique), void *hook);
-extern int afs_dir_IsEmpty (char *dir);
-extern struct DirEntry *afs_dir_GetBlob (char *dir, afs_int32 blobno);
+extern int afs_dir_Create (void *dir, char *entry, void *vfid);
+extern int afs_dir_Length (void *dir);
+extern int afs_dir_Delete (void *dir, char *entry);
+extern int afs_dir_MakeDir (void *dir, afs_int32 *me, afs_int32 *parent);
+extern int afs_dir_Lookup (void *dir, char *entry, void *fid);
+extern int afs_dir_LookupOffset (void *dir, char *entry, void *fid, long *offsetp);
+extern int afs_dir_EnumerateDir (void *dir, int (*hookproc)(void *dir, char *name, afs_int32 vnode, afs_int32 unique), void *hook);
+extern int afs_dir_IsEmpty (void *dir);
+extern struct DirEntry *afs_dir_GetBlob (void *dir, afs_int32 blobno);
#endif
-
-
#endif /* !defined(__AFS_DIR_H) */