/*
* 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
#include <afsconfig.h>
#include "afs/param.h"
-RCSID
- ("$Header$");
#include "afs/sysincludes.h" /*Standard vendor system headers */
#include "afsincludes.h" /*AFS-based standard headers */
* look into interactions of dnlc and readdir.
* cache larger names, perhaps by using a better,longer key (SHA) and discarding
* the actual name itself.
- * precompute a key and stuff for @sys, and combine the HandleAtName function with
- * this, since we're looking at the name anyway.
+ * precompute a key and stuff for \sys, and combine the HandleAtName function with
+ * this, since we're looking at the name anyway.
*/
struct afs_lock afs_xdnlc;
ObtainWriteLock(&afs_xdnlc, 222);
/* Only cache entries from the latest version of the directory */
- if (!(adp->states & CStatd) || !hsame(*avno, adp->m.DataVersion)) {
+ if (!(adp->f.states & CStatd) || !hsame(*avno, adp->f.m.DataVersion)) {
ReleaseWriteLock(&afs_xdnlc);
return 0;
}
osi_dnlc_lookup(struct vcache *adp, char *aname, int locktype)
{
struct vcache *tvc;
- int LRUme;
unsigned int key, skey;
char *ts = aname;
- struct nc *tnc, *tnc1 = 0;
+ struct nc *tnc;
int safety;
+#ifdef AFS_DARWIN80_ENV
+ vnode_t tvp;
+#endif
if (!afs_usednlc)
- return 0;
+ return 0;
dnlcHash(ts, key); /* leaves ts pointing at the NULL */
- if (ts - aname >= AFSNCNAMESIZE) {
- return 0;
- }
+ if (ts - aname >= AFSNCNAMESIZE)
+ return 0;
skey = key & (NHSIZE - 1);
TRACE(osi_dnlc_lookupT, skey);
if ( /* (tnc->key == key) && */ (tnc->dirp == adp)
&& (!strcmp((char *)tnc->name, aname))) {
tvc = tnc->vp;
- tnc1 = tnc;
break;
} else if (tnc->next == nameHash[skey]) { /* end of list */
break;
}
}
- LRUme = 0; /* (tnc != nameHash[skey]); */
ReleaseReadLock(&afs_xdnlc);
if (!tvc) {
ReleaseReadLock(&afs_xvcache);
dnlcstats.misses++;
} else {
- if (tvc->states & CVInit) {
+ if ((tvc->f.states & CVInit)
+#ifdef AFS_DARWIN80_ENV
+ ||(tvc->f.states & CDeadVnode)
+#endif
+ )
+ {
ReleaseReadLock(&afs_xvcache);
dnlcstats.misses++;
osi_dnlc_remove(adp, aname, tvc);
return 0;
}
-#ifdef AFS_OSF_ENV
- VN_HOLD((vnode_t *) tvc);
-#else
-#ifdef AFS_DARWIN80_ENV
- if (vnode_get(tvc->v)) {
+#if defined(AFS_DARWIN80_ENV)
+ tvp = AFSTOV(tvc);
+ if (vnode_get(tvp)) {
ReleaseReadLock(&afs_xvcache);
dnlcstats.misses++;
- osi_dnlc_remove(adp, aname, tvc);
- return 0;
- }
-#endif
+ osi_dnlc_remove(adp, aname, tvc);
+ return 0;
+ }
+ if (vnode_ref(tvp)) {
+ ReleaseReadLock(&afs_xvcache);
+ AFS_GUNLOCK();
+ vnode_put(tvp);
+ AFS_GLOCK();
+ dnlcstats.misses++;
+ osi_dnlc_remove(adp, aname, tvc);
+ return 0;
+ }
+#else
osi_vnhold(tvc, 0);
#endif
ReleaseReadLock(&afs_xvcache);
-#ifdef notdef
- /*
- * XX If LRUme ever is non-zero change the if statement around because
- * aix's cc with optimizer on won't necessarily check things in order XX
- */
- if (LRUme && (0 == NBObtainWriteLock(&afs_xdnlc))) {
- /* don't block to do this */
- /* tnc might have been moved during race condition, */
- /* but it's always in a legit hash chain when a lock is granted,
- * or else it's on the freelist so prev == NULL,
- * so at worst this is redundant */
- /* Now that we've got it held, and a lock on the dnlc, we
- * should check to be sure that there was no race, and
- * bail out if there was. */
- if (tnc->prev) {
- /* special case for only two elements on list - relative ordering
- * doesn't change */
- if (tnc->prev != tnc->next) {
- /* remove from old location */
- tnc->prev->next = tnc->next;
- tnc->next->prev = tnc->prev;
- /* insert into new location */
- tnc->next = nameHash[skey];
- tnc->prev = tnc->next->prev;
- tnc->next->prev = tnc;
- tnc->prev->next = tnc;
- }
- nameHash[skey] = tnc;
- }
- ReleaseWriteLock(&afs_xdnlc);
- }
-#endif
}
return tvc;
return 0;
}
-/* remove anything pertaining to this directory. I can invalidate
+/*!
+ * Remove anything pertaining to this directory. I can invalidate
* things without the lock, since I am just looking through the array,
* but to move things off the lists or into the freelist, I need the
- * write lock */
+ * write lock
+ *
+ * \param adp vcache entry for the directory to be purged.
+ * \return 0
+ */
int
osi_dnlc_purgedp(struct vcache *adp)
{
int writelocked;
#ifdef AFS_DARWIN_ENV
- if (!(adp->states & (CVInit | CVFlushed
+ if (!(adp->f.states & (CVInit | CVFlushed
#ifdef AFS_DARWIN80_ENV
| CDeadVnode
#endif
return 0;
}
-/* remove anything pertaining to this file */
+/*!
+ * Remove anything pertaining to this file
+ *
+ * \param File vcache entry.
+ * \return 0
+ */
int
osi_dnlc_purgevp(struct vcache *avc)
{
int writelocked;
#ifdef AFS_DARWIN_ENV
- if (!(avc->states & (CVInit | CVFlushed
+ if (!(avc->f.states & (CVInit | CVFlushed
#ifdef AFS_DARWIN80_ENV
| CDeadVnode
#endif
nameCache[i].dirp = nameCache[i].vp = NULL;
} else { /* did get the lock */
ncfreelist = NULL;
- memset((char *)nameCache, 0, sizeof(struct nc) * NCSIZE);
- memset((char *)nameHash, 0, sizeof(struct nc *) * NHSIZE);
+ memset(nameCache, 0, sizeof(struct nc) * NCSIZE);
+ memset(nameHash, 0, sizeof(struct nc *) * NHSIZE);
for (i = 0; i < NCSIZE; i++) {
nameCache[i].next = ncfreelist;
ncfreelist = &nameCache[i];
int i;
Lock_Init(&afs_xdnlc);
- memset((char *)&dnlcstats, 0, sizeof(dnlcstats));
- memset((char *)dnlctracetable, 0, sizeof(dnlctracetable));
+ memset(&dnlcstats, 0, sizeof(dnlcstats));
+ memset(dnlctracetable, 0, sizeof(dnlctracetable));
dnlct = 0;
ObtainWriteLock(&afs_xdnlc, 223);
ncfreelist = NULL;
- memset((char *)nameCache, 0, sizeof(struct nc) * NCSIZE);
- memset((char *)nameHash, 0, sizeof(struct nc *) * NHSIZE);
+ memset(nameCache, 0, sizeof(struct nc) * NCSIZE);
+ memset(nameHash, 0, sizeof(struct nc *) * NHSIZE);
for (i = 0; i < NCSIZE; i++) {
nameCache[i].next = ncfreelist;
ncfreelist = &nameCache[i];