ShakeLooseVCaches needs to avoid CVInit vcaches
[openafs.git] / src / afs / afs_vcache.c
index f564d19..117c919 100644 (file)
@@ -58,9 +58,7 @@ char *makesname();
 #endif /* AFS_SGI64_ENV */
 
 /* Exported variables */
-#ifdef AFS_DISCON_ENV
 afs_rwlock_t afs_xvcdirty;     /*Lock: discon vcache dirty list mgmt */
-#endif
 afs_rwlock_t afs_xvcache;      /*Lock: alloc new stat cache entries */
 afs_rwlock_t afs_xvreclaim;    /*Lock: entries reclaimed, not on free list */
 afs_lock_t afs_xvcb;           /*Lock: fids on which there are callbacks */
@@ -81,10 +79,8 @@ int afs_norefpanic = 0;
 
 /* Disk backed vcache definitions 
  * Both protected by xvcache */
-#ifdef AFS_DISCON_ENV
 static int afs_nextVcacheSlot = 0;
 static struct afs_slotlist *afs_freeSlotList = NULL;
-#endif
 
 /* Forward declarations */
 static afs_int32 afs_QueueVCB(struct vcache *avc);
@@ -297,17 +293,21 @@ afs_InactiveVCache(struct vcache *avc, afs_ucred_t *acred)
  */
 static struct afs_cbr *afs_cbrSpace = 0;
 /* if alloc limit below changes, fix me! */
-static struct afs_cbr *afs_cbrHeads[2];
+static struct afs_cbr *afs_cbrHeads[16];
 struct afs_cbr *
 afs_AllocCBR(void)
 {
     register struct afs_cbr *tsp;
     int i;
 
-    while (!afs_cbrSpace) {
-       if (afs_stats_cmperf.CallBackAlloced >= 2) {
-           /* don't allocate more than 2 * AFS_NCBRS for now */
-           afs_FlushVCBs(0);
+    if (!afs_cbrSpace) {
+       afs_osi_CancelWait(&AFS_WaitHandler);   /* trigger FlushVCBs asap */
+
+       if (afs_stats_cmperf.CallBackAlloced >= sizeof(afs_cbrHeads)/sizeof(afs_cbrHeads[0])) {
+           /* don't allocate more than 16 * AFS_NCBRS for now */
+           tsp = (struct afs_cbr *)osi_AllocSmallSpace(sizeof(*tsp));
+           tsp->dynalloc = 1;
+           tsp->next = NULL;
            afs_stats_cmperf.CallBackFlushes++;
        } else {
            /* try allocating */
@@ -316,15 +316,18 @@ afs_AllocCBR(void)
                                                sizeof(struct afs_cbr));
            for (i = 0; i < AFS_NCBRS - 1; i++) {
                tsp[i].next = &tsp[i + 1];
+               tsp[i].dynalloc = 0;
            }
            tsp[AFS_NCBRS - 1].next = 0;
-           afs_cbrSpace = tsp;
+           tsp[AFS_NCBRS - 1].dynalloc = 0;
+           afs_cbrSpace = tsp->next;
            afs_cbrHeads[afs_stats_cmperf.CallBackAlloced] = tsp;
            afs_stats_cmperf.CallBackAlloced++;
        }
+    } else {
+       tsp = afs_cbrSpace;
+       afs_cbrSpace = tsp->next;
     }
-    tsp = afs_cbrSpace;
-    afs_cbrSpace = tsp->next;
     return tsp;
 }
 
@@ -348,8 +351,12 @@ afs_FreeCBR(register struct afs_cbr *asp)
     if (asp->hash_next)
        asp->hash_next->hash_pprev = asp->hash_pprev;
 
-    asp->next = afs_cbrSpace;
-    afs_cbrSpace = asp;
+    if (asp->dynalloc) {
+       osi_FreeSmallSpace(asp);
+    } else {
+       asp->next = afs_cbrSpace;
+       afs_cbrSpace = asp;
+    }
     return 0;
 }
 
@@ -659,6 +666,8 @@ afs_ShakeLooseVCaches(afs_int32 anumber)
            refpanic("Exceeded pool of AFS vnodes(VLRU cycle?)");
        } else if (QNext(uq) != tq) {
            refpanic("VLRU inconsistent");
+       } else if (tvc->f.states & CVInit) {
+           continue;
        }
 
        fv_slept = 0;
@@ -702,7 +711,6 @@ afs_AllocVCache(void)
 
     afs_stats_cmperf.vcacheXAllocs++;  /* count in case we have a leak */
 
-#ifdef AFS_DISCON_ENV
     /* If we create a new inode, we either give it a new slot number,
      * or if one's available, use a slot number from the slot free list
      */
@@ -716,7 +724,6 @@ afs_AllocVCache(void)
     }  else {
        tvc->diskSlot = afs_nextVcacheSlot++;
     }
-#endif
 
     return tvc;
 }
@@ -729,17 +736,13 @@ static void
 afs_PrePopulateVCache(struct vcache *avc, struct VenusFid *afid,
                      struct server *serverp) {
 
-#if defined(AFS_DISCON_ENV)
     afs_uint32 slot;
     slot = avc->diskSlot;
-#endif
 
     osi_PrePopulateVCache(avc);
 
-#if defined(AFS_DISCON_ENV)
     avc->diskSlot = slot;
     QZero(&avc->metadirty);
-#endif
 
     AFS_RWLOCK_INIT(&avc->lock, "vcache lock");
 
@@ -860,7 +863,7 @@ afs_NewVCache_int(struct VenusFid *afid, struct server *serverp, int seq)
 
 #if defined(AFS_LINUX22_ENV)
     /* Hold it for the LRU (should make count 2) */
-    VN_HOLD(AFSTOV(tvc));
+    AFS_FAST_HOLD(tvc);
 #elif !(defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV))
     VREFCOUNT_SET(tvc, 1);     /* us */
 #endif
@@ -1265,7 +1268,6 @@ afs_WriteVCache(register struct vcache *avc,
     return code;
 
 }                              /*afs_WriteVCache */
-#if defined(AFS_DISCON_ENV)
 
 /*!
  * Store status info only locally, set the proper disconnection flags
@@ -1345,8 +1347,6 @@ afs_WriteVCacheDiscon(register struct vcache *avc,
     return code;
 }
 
-#endif
-
 /*!
  * Copy astat block into vcache info
  *