#include "h/errno.h"
#endif
#include "h/time.h"
-#if defined(AFS_AIX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_FBSD_ENV)
+#if defined(AFS_AIX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX20_ENV)
#include "h/errno.h"
#else
#if !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV)
#include "h/kernel.h"
#endif
#endif
-#if defined(AFS_SUN56_ENV) || defined(AFS_HPUX_ENV)
+#if defined(AFS_SUN56_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_FBSD_ENV) || defined(AFS_DARWIN80_ENV)
#include "afs/sysincludes.h"
#endif
-#if defined(AFS_FBSD_ENV)
-#include "h/lock.h"
-#include "vm/vm.h"
-#include "vm/vm_extern.h"
-#include "vm/pmap.h"
-#include "vm/vm_map.h"
-#endif /* AFS_FBSD_ENV */
#if !defined(AFS_SGI64_ENV) && !defined(AFS_DARWIN60_ENV)
#include "h/user.h"
#endif /* AFS_SGI64_ENV */
#include "h/uio.h"
-#ifdef AFS_DEC_ENV
-#include "afs/gfs_vfs.h"
-#include "afs/gfs_vnode.h"
-#else
-#ifdef AFS_MACH_ENV
-#ifdef NeXT
-#include <sys/vfs.h>
-#include <sys/vnode.h>
-#include <ufs/inode.h>
-#else
-#include <vfs/vfs.h>
-#include <vfs/vnode.h>
-#include <sys/inode.h>
-#endif /* NeXT */
-#else /* AFS_MACH_ENV */
#ifdef AFS_OSF_ENV
#include <sys/mount.h>
#include <sys/vnode.h>
#include <ufs/inode.h>
-#else /* AFS_OSF_ENV */
-#ifdef AFS_SUN5_ENV
-#else
-#if !defined(AFS_SGI_ENV)
-#endif
-#endif /* AFS_OSF_ENV */
-#endif /* AFS_MACH_ENV */
-#endif
#endif
#if !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_HPUX110_ENV)
#include "h/mbuf.h"
#ifndef AFS_LINUX20_ENV
#include "netinet/in.h"
#endif
+
+/* afs_buffer.c */
+/* These are needed because afs_prototypes.h is not included here */
+extern void *DRead(struct dcache *adc, int page);
+extern void *DNew(struct dcache *adc, int page);
+
#else /* !defined(UKERNEL) */
#include "afs/stds.h"
#include "afs/sysincludes.h"
+
+/* afs_buffer.c */
+/* These are needed because afs_prototypes.h is not included here */
+extern void *DRead(register afs_int32 *fid, register int page);
+extern void *DNew(register afs_int32 *fid, register int page);
+
#endif /* !defined(UKERNEL) */
#include "afs/afs_osi.h"
#define LookupOffset afs_dir_LookupOffset
#define EnumerateDir afs_dir_EnumerateDir
#define IsEmpty afs_dir_IsEmpty
+#define InverseLookup afs_dir_InverseLookup
+
+#if defined(AFS_DISCON_ENV)
+#define ChangeFid afs_dir_ChangeFid
+#endif
+
#else /* KERNEL */
# ifdef HAVE_UNISTD_H
#include <netinet/in.h>
#endif
-#ifdef HAVE_STRING_H
#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
#endif /* KERNEL */
afs_int32 DErrno;
-char *DRelease();
-struct DirEntry *DRead();
-struct DirEntry *DNew();
/* Local static prototypes */
static struct DirEntry *FindItem(void *dir, char *ename,
/* First check if file already exists. */
ep = FindItem(dir, entry, &pp);
if (ep) {
- DRelease(ep, 0);
- DRelease(pp, 0);
+ DRelease((struct buffer *)ep, 0);
+ DRelease((struct buffer *)pp, 0);
return EEXIST;
}
blobs = NameBlobs(entry); /* number of entries required */
/* Now we just have to thread it on the hash table list. */
dhp = (struct DirHeader *)DRead(dir, 0);
if (!dhp) {
- DRelease(ep, 1);
+ DRelease((struct buffer *)ep, 1);
return EIO;
}
i = DirHash(entry);
ep->next = dhp->hashTable[i];
dhp->hashTable[i] = htons(firstelt);
- DRelease(dhp, 1);
- DRelease(ep, 1);
+ DRelease((struct buffer *)dhp, 1);
+ DRelease((struct buffer *)ep, 1);
return 0;
}
if (dhp->alloMap[i] != EPP)
ctr++;
}
- DRelease(dhp, 0);
+ DRelease((struct buffer *)dhp, 0);
return ctr * AFS_PAGESIZE;
}
if (firstitem == 0)
return ENOENT;
*previtem = firstitem->next;
- DRelease(previtem, 1);
+ DRelease((struct buffer *)previtem, 1);
index = DVOffset(firstitem) / 32;
nitems = NameBlobs(firstitem->name);
- DRelease(firstitem, 0);
+ DRelease((struct buffer *)firstitem, 0);
FreeBlobs(dir, index, nitems);
return 0;
}
}
pp = (struct PageHeader *)DRead(dir, i); /* read the page in. */
if (!pp) {
- DRelease(dhp, 1);
+ DRelease((struct buffer *)dhp, 1);
break;
}
for (j = 0; j <= EPP - nblobs; j++) {
* and free up any resources we've got allocated. */
if (i < MAXPAGES)
dhp->alloMap[i] -= nblobs;
- DRelease(dhp, 1);
+ DRelease((struct buffer *)dhp, 1);
for (k = 0; k < nblobs; k++)
pp->freebitmap[(j + k) >> 3] |= 1 << ((j + k) & 7);
- DRelease(pp, 1);
+ DRelease((struct buffer *)pp, 1);
return j + i * EPP;
}
- DRelease(pp, 0); /* This dir page is unchanged. */
+ DRelease((struct buffer *)pp, 0); /* This dir page is unchanged. */
}
}
/* If we make it here, the directory is full. */
- DRelease(dhp, 1);
+ DRelease((struct buffer *)dhp, 1);
return -1;
}
pp->freebitmap[0] = 0x01;
for (i = 1; i < EPP / 8; i++) /* It's a constant */
pp->freebitmap[i] = 0;
- DRelease(pp, 1);
+ DRelease((struct buffer *)pp, 1);
}
/* Free a whole bunch of directory entries. */
return;
if (page < MAXPAGES)
dhp->alloMap[page] += nblobs;
- DRelease(dhp, 1);
+ DRelease((struct buffer *)dhp, 1);
pp = (struct PageHeader *)DRead(dir, page);
if (pp)
for (i = 0; i < nblobs; i++)
pp->freebitmap[(firstblob + i) >> 3] &=
~(1 << ((firstblob + i) & 7));
- DRelease(pp, 1);
+ DRelease((struct buffer *)pp, 1);
}
/*
dhp->alloMap[i] = EPP;
for (i = 0; i < NHASHENT; i++)
dhp->hashTable[i] = 0;
- DRelease(dhp, 1);
+ DRelease((struct buffer *)dhp, 1);
Create(dir, ".", me);
Create(dir, "..", parent); /* Virtue is its own .. */
return 0;
firstitem = FindItem(dir, entry, &previtem);
if (firstitem == 0)
return ENOENT;
- DRelease(previtem, 0);
+ DRelease((struct buffer *)previtem, 0);
fid[1] = ntohl(firstitem->fid.vnode);
fid[2] = ntohl(firstitem->fid.vunique);
- DRelease(firstitem, 0);
+ DRelease((struct buffer *)firstitem, 0);
return 0;
}
firstitem = FindItem(dir, entry, &previtem);
if (firstitem == 0)
return ENOENT;
- DRelease(previtem, 0);
+ DRelease((struct buffer *)previtem, 0);
fid[1] = ntohl(firstitem->fid.vnode);
fid[2] = ntohl(firstitem->fid.vunique);
if (offsetp)
*offsetp = DVOffset(firstitem);
- DRelease(firstitem, 0);
+ DRelease((struct buffer *)firstitem, 0);
return 0;
}
int
-EnumerateDir(void *dir, int (*hookproc) (), void *hook)
+EnumerateDir(void *dir, int (*hookproc) (void *dir, char *name,
+ afs_int32 vnode, afs_int32 unique),
+ void *hook)
{
- /* Enumerate the contents of a directory. */
+ /* Enumerate the contents of a directory.
+ * Break when hook function returns non 0.
+ */
register int i;
int num;
register struct DirHeader *dhp;
register struct DirEntry *ep;
+ int code = 0;
dhp = (struct DirHeader *)DRead(dir, 0);
if (!dhp)
return EIO; /* first page should be there */
+
for (i = 0; i < NHASHENT; i++) {
/* For each hash chain, enumerate everyone on the list. */
num = ntohs(dhp->hashTable[i]);
if (!ep) {
if (DErrno) {
/* we failed, return why */
- DRelease(dhp, 0);
+ DRelease((struct buffer *)dhp, 0);
return DErrno;
}
break;
}
+
num = ntohs(ep->next);
- (*hookproc) (hook, ep->name, ntohl(ep->fid.vnode),
+ code = (*hookproc) (hook, ep->name, ntohl(ep->fid.vnode),
ntohl(ep->fid.vunique));
- DRelease(ep, 0);
+ DRelease((struct buffer *)ep, 0);
+ if (code)
+ break;
}
}
- DRelease(dhp, 0);
+ DRelease((struct buffer *)dhp, 0);
return 0;
}
if (!ep)
break;
if (strcmp(ep->name, "..") && strcmp(ep->name, ".")) {
- DRelease(ep, 0);
- DRelease(dhp, 0);
+ DRelease((struct buffer *)ep, 0);
+ DRelease((struct buffer *)dhp, 0);
return 1;
}
num = ntohs(ep->next);
- DRelease(ep, 0);
+ DRelease((struct buffer *)ep, 0);
}
}
- DRelease(dhp, 0);
+ DRelease((struct buffer *)dhp, 0);
return 0;
}
{
/* Hash a string to a number between 0 and NHASHENT. */
register unsigned char tc;
- register int hval;
+ unsigned int hval;
register int tval;
hval = 0;
while ((tc = (*string++))) {
tval = hval & (NHASHENT - 1);
if (tval == 0)
return tval;
- else if (hval < 0)
+ else if (hval >= 1<<31)
tval = NHASHENT - tval;
return tval;
}
return 0;
if (dhp->hashTable[i] == 0) {
/* no such entry */
- DRelease(dhp, 0);
+ DRelease((struct buffer *)dhp, 0);
return 0;
}
tp = GetBlob(dir, (u_short) ntohs(dhp->hashTable[i]));
if (!tp) {
- DRelease(dhp, 0);
+ DRelease((struct buffer *)dhp, 0);
return 0;
}
lp = &(dhp->hashTable[i]);
*previtem = lp;
return tp;
}
- DRelease(lp, 0);
+ DRelease((struct buffer *)lp, 0);
lp = &(tp->next);
if (tp->next == 0) {
/* The end of the line */
- DRelease(lp, 0); /* Release all locks. */
+ DRelease((struct buffer *)lp, 0); /* Release all locks. */
return 0;
}
tp = GetBlob(dir, (u_short) ntohs(tp->next));
if (!tp) {
- DRelease(lp, 0);
+ DRelease((struct buffer *)lp, 0);
return 0;
}
}
}
+
+static struct DirEntry *
+FindFid (void *dir, afs_uint32 vnode, afs_uint32 unique)
+{
+ /* Find a directory entry, given the vnode and uniquifier of a object.
+ * This entry returns a pointer to a locked buffer. If no entry is found,
+ * however, no items are left locked, and a null pointer is returned
+ * instead.
+ */
+ register int i;
+ register struct DirHeader *dhp;
+ register unsigned short *lp;
+ register struct DirEntry *tp;
+ dhp = (struct DirHeader *) DRead(dir,0);
+ if (!dhp) return 0;
+ for (i=0; i<NHASHENT; i++) {
+ if (dhp->hashTable[i] != 0) {
+ tp = GetBlob(dir,(u_short)ntohs(dhp->hashTable[i]));
+ if (!tp) { /* should not happen */
+ DRelease(dhp, 0);
+ return 0;
+ }
+ while(tp) {
+ if (vnode == ntohl(tp->fid.vnode)
+ && unique == ntohl(tp->fid.vunique)) {
+ DRelease(dhp,0);
+ return tp;
+ }
+ lp = &(tp->next);
+ if (tp->next == 0)
+ break;
+ tp = GetBlob(dir,(u_short)ntohs(tp->next));
+ DRelease(lp,0);
+ }
+ DRelease(lp,0);
+ }
+ }
+ DRelease(dhp,0);
+ return (struct DirEntry *)0;
+}
+
+int
+InverseLookup (void *dir, afs_uint32 vnode, afs_uint32 unique, char *name,
+ afs_uint32 length)
+{
+ /* Look for the name pointing to given vnode and unique in a directory */
+ register struct DirEntry *entry;
+ int code = 0;
+
+ entry = FindFid(dir, vnode, unique);
+ if (!entry)
+ return ENOENT;
+ if (strlen(entry->name) >= length)
+ code = E2BIG;
+ else
+ strcpy(name, entry->name);
+ DRelease(entry, 0);
+ return code;
+}
+
+#if defined(AFS_DISCON_ENV)
+/*!
+ * Change an entry fid.
+ *
+ * \param dir
+ * \param entry The entry name.
+ * \param old_fid The old find in MKFid format (host order).
+ * It can be omitted if you don't need a safety check...
+ * \param new_fid The new find in MKFid format (host order).
+ */
+int ChangeFid(void *dir,
+ char *entry,
+ afs_uint32 *old_fid,
+ afs_uint32 *new_fid)
+{
+ struct DirEntry *firstitem;
+ unsigned short *previtem;
+ struct MKFid *fid_old = (struct MKFid *) old_fid;
+ struct MKFid *fid_new = (struct MKFid *) new_fid;
+
+ /* Find entry. */
+ firstitem = FindItem(dir, entry, &previtem);
+ if (firstitem == 0) {
+ return ENOENT;
+ }
+ DRelease(previtem, 1);
+ /* Replace fid. */
+ if (!old_fid ||
+ ((htonl(fid_old->vnode) == firstitem->fid.vnode) &&
+ (htonl(fid_old->vunique) == firstitem->fid.vunique))) {
+
+ firstitem->fid.vnode = htonl(fid_new->vnode);
+ firstitem->fid.vunique = htonl(fid_new->vunique);
+ }
+
+ DRelease(firstitem, 1);
+
+ return 0;
+}
+#endif