make-clearcallback-faster-20050524
[openafs.git] / src / afs / afs_vcache.c
index 0d19994..3dc65f4 100644 (file)
@@ -69,6 +69,7 @@ struct afs_q VLRU;            /*vcache LRU */
 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;
@@ -129,8 +130,8 @@ int
 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);
@@ -174,7 +175,18 @@ afs_FlushVCache(struct vcache *avc, int *slept)
            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);
@@ -187,12 +199,8 @@ afs_FlushVCache(struct vcache *avc, int *slept)
     /* 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));
@@ -235,7 +243,7 @@ afs_FlushVCache(struct vcache *avc, int *slept)
     /* 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 {
@@ -580,7 +588,7 @@ struct vcache *
 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;
@@ -619,11 +627,10 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
                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) {
@@ -716,13 +723,12 @@ restart:
            }
 #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(),
@@ -813,12 +819,8 @@ restart:
     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;
@@ -1084,9 +1086,12 @@ restart:
     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");
     }
@@ -1178,7 +1183,7 @@ afs_FlushActiveVcaches(register afs_int32 doflocks)
                /*
                 * 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);
@@ -1738,7 +1743,7 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq,
 #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);
@@ -1748,11 +1753,7 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq,
        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)
@@ -2853,7 +2854,7 @@ shutdown_vcache(void)
                    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) {
@@ -2875,7 +2876,7 @@ shutdown_vcache(void)
 
                afs_FreeAllAxs(&(tvc->Access));
            }
-           afs_vhashT[i] = 0;
+           afs_vhashT[i] = afs_vhashTV[i] = 0;
        }
     }
     /*