#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 */
/* 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);
*/
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 */
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;
}
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;
}
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;
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
*/
} else {
tvc->diskSlot = afs_nextVcacheSlot++;
}
-#endif
return tvc;
}
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");
#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
return code;
} /*afs_WriteVCache */
-#if defined(AFS_DISCON_ENV)
/*!
* Store status info only locally, set the proper disconnection flags
return code;
}
-#endif
-
/*!
* Copy astat block into vcache info
*