afs_int32 vcachegen = 0;
unsigned int afs_paniconwarn = 0;
struct vcache *afs_vhashT[VCSIZE];
+struct vcache *afs_vhashTV[VCSIZE];
static struct afs_cbr *afs_cbrHashT[CBRSIZE];
afs_int32 afs_bulkStatsLost;
int afs_norefpanic = 0;
afs_FlushVCache(struct vcache *avc, int *slept)
{ /*afs_FlushVCache */
- register afs_int32 i, code;
- register struct vcache **uvc, *wvc;
+ afs_int32 i, code, j;
+ struct vcache **uvc, *wvc, **uvc2, *wvc2;
*slept = 0;
AFS_STATCNT(afs_FlushVCache);
break;
}
}
- if (!wvc)
+
+ /* remove entry from the volume hash table */
+ j = VCHashV(&avc->fid);
+ uvc2 = &afs_vhashTV[j];
+ for (wvc2 = *uvc2; wvc2; uvc2 = &wvc2->vhnext, wvc2 = *uvc2) {
+ if (avc == wvc2) {
+ *uvc2 = avc->vhnext;
+ avc->vhnext = (struct vcache *)NULL;
+ break;
+ }
+ }
+ if (!wvc || !wvc2)
osi_Panic("flushvcache"); /* not in correct hash bucket */
if (avc->mvid)
osi_FreeSmallSpace(avc->mvid);
/* OK, there are no internal vrefCounts, so there shouldn't
* be any more refs here. */
if (avc->v) {
-#ifdef AFS_DARWIN_ENV
- vnode_clearfsnode(AFSTOV(avc));
-#else
avc->v->v_data = NULL; /* remove from vnode */
-#endif
- AFSTOV(avc) = NULL; /* also drop the ptr to vnode */
+ avc->v = NULL; /* also drop the ptr to vnode */
}
#endif
afs_FreeAllAxs(&(avc->Access));
/* This should put it back on the vnode free list since usecount is 1 */
afs_vcount--;
vSetType(avc, VREG);
- if (VREFCOUNT_GT(avc,0)) {
+ if (VREFCOUNT(avc) > 0) {
VN_UNLOCK(AFSTOV(avc));
AFS_RELE(AFSTOV(avc));
} else {
afs_NewVCache(struct VenusFid *afid, struct server *serverp)
{
struct vcache *tvc;
- afs_int32 i;
+ afs_int32 i, j;
afs_int32 anumber = VCACHE_FREE;
#ifdef AFS_AIX_ENV
struct gnode *gnodepnt;
refpanic("Exceeded pool of AFS vnodes(VLRU cycle?)");
else if (QNext(uq) != tq)
refpanic("VLRU inconsistent");
- else if (!VREFCOUNT_GT(tvc,0))
- refpanic("refcnt 0 on VLRU");
-
- if (VREFCOUNT_GT(tvc,0) && !VREFCOUNT_GT(tvc,1) &&
- tvc->opens == 0
+ else if (VREFCOUNT(tvc) < 1)
+ refpanic("refcnt 0 on VLRU");
+
+ if (VREFCOUNT(tvc) == 1 && tvc->opens == 0
&& (tvc->states & CUnlinkedDel) == 0) {
code = afs_FlushVCache(tvc, &fv_slept);
if (code == 0) {
}
#endif
-
- if (!VREFCOUNT_GT(tvc,0)
-#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL) && !defined(AFS_DARWIN80_ENV)
- || ((VREFCOUNT(tvc) == 1) &&
- (UBCINFOEXISTS(AFSTOV(tvc))))
+ if (((VREFCOUNT(tvc) == 0)
+#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL)
+ || ((VREFCOUNT(tvc) == 1) &&
+ (UBCINFOEXISTS(AFSTOV(tvc))))
#endif
- && tvc->opens == 0 && (tvc->states & CUnlinkedDel) == 0) {
+ ) && tvc->opens == 0 && (tvc->states & CUnlinkedDel) == 0) {
#if defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
/*
* vgone() reclaims the vnode, which calls afs_FlushVCache(),
AFS_GUNLOCK();
afs_darwin_getnewvnode(tvc); /* includes one refcount */
AFS_GLOCK();
-#ifdef AFS_DARWIN80_ENV
- LOCKINIT(tvc->rwlock);
-#else
lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0);
#endif
-#endif
#ifdef AFS_FBSD_ENV
{
struct vnode *vp;
memset((char *)&(tvc->callsort), 0, sizeof(struct afs_q));
tvc->slocks = NULL;
i = VCHash(afid);
+ j = VCHashV(afid);
tvc->hnext = afs_vhashT[i];
- afs_vhashT[i] = tvc;
+ tvc->vhnext = afs_vhashTV[j];
+ afs_vhashT[i] = afs_vhashTV[j] = tvc;
+
if ((VLRU.next->prev != &VLRU) || (VLRU.prev->next != &VLRU)) {
refpanic("NewVCache VLRU inconsistent");
}
/*
* That's because if we come in via the CUnlinkedDel bit state path we'll be have 0 refcnt
*/
- osi_Assert(VREFCOUNT_GT(tvc,0));
+ osi_Assert(VREFCOUNT(tvc) > 0);
AFS_RWLOCK((vnode_t *) tvc, VRWLOCK_WRITE);
#endif
ObtainWriteLock(&tvc->lock, 52);
#if defined(AFS_DARWIN_ENV)
iheldthelock = VOP_ISLOCKED(vp);
if (!iheldthelock)
- vnode_lock(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, current_proc());
/* this is messy. we can call fsync which will try to reobtain this */
if (VTOAFS(vp) == tvc)
ReleaseWriteLock(&tvc->lock);
if (VTOAFS(vp) == tvc)
ObtainWriteLock(&tvc->lock, 954);
if (!iheldthelock)
-#ifdef AFS_DARWIN80_ENV
- vnode_unlock(vp);
-#else
VOP_UNLOCK(vp, LK_EXCLUSIVE, current_proc());
-#endif
#elif defined(AFS_FBSD60_ENV)
iheldthelock = VOP_ISLOCKED(vp, curthread);
if (!iheldthelock)
vms_delete(tvc->segid);
AFS_GLOCK();
tvc->segid = tvc->vmh = NULL;
- if (VREFCOUNT_GT(tvc,0))
+ if (VREFCOUNT(tvc))
osi_Panic("flushVcache: vm race");
}
if (tvc->credp) {
afs_FreeAllAxs(&(tvc->Access));
}
- afs_vhashT[i] = 0;
+ afs_vhashT[i] = afs_vhashTV[i] = 0;
}
}
/*