u_int afs_min_cache = 0;
/*!
+ * If there are waiters for the cache to drain, wake them if
+ * the number of free or discarded cache blocks reaches the
+ * CM_CACHESIZEDDRAINEDPCT limit.
+ *
+ * \note Environment:
+ * This routine must be called with the afs_xdcache lock held
+ * (in write mode).
+ */
+static void
+afs_WakeCacheWaitersIfDrained(void)
+{
+ if (afs_WaitForCacheDrain) {
+ if ((afs_blocksUsed - afs_blocksDiscarded) <=
+ PERCENT(CM_CACHESIZEDRAINEDPCT, afs_cacheBlocks)) {
+ afs_WaitForCacheDrain = 0;
+ afs_osi_Wakeup(&afs_WaitForCacheDrain);
+ }
+ }
+}
+
+/*!
* Keeps the cache clean and free by truncating uneeded files, when used.
* \param
* \return
while (1) {
cb_lowat = PERCENT((CM_DCACHESPACEFREEPCT - CM_DCACHEEXTRAPCT), afs_cacheBlocks);
ObtainWriteLock(&afs_xdcache, 266);
- if (afs_CacheTooFull) {
+ if (afs_CacheTooFull || afs_WaitForCacheDrain) {
int space_needed, slots_needed;
/* if we get woken up, we should try to clean something out */
for (counter = 0; counter < 10; counter++) {
if (slots_needed || space_needed)
afs_GetDownD(slots_needed, &space_needed, 0);
if ((space_needed <= 0) && (slots_needed <= 0)) {
- afs_CacheTooFull = 0;
break;
}
if (afs_termState == AFSOP_STOP_TRUNCDAEMON)
break;
}
- if (!afs_CacheIsTooFull())
+ if (!afs_CacheIsTooFull()) {
afs_CacheTooFull = 0;
+ afs_WakeCacheWaitersIfDrained();
+ }
} /* end of cache cleanup */
ReleaseWriteLock(&afs_xdcache);
} else {
afs_FreeDCache(adc);
}
-
- if (afs_WaitForCacheDrain) {
- if (afs_blocksUsed <=
- PERCENT(CM_CACHESIZEDRAINEDPCT, afs_cacheBlocks)) {
- afs_WaitForCacheDrain = 0;
- afs_osi_Wakeup(&afs_WaitForCacheDrain);
- }
- }
} /*afs_FlushDCache */
afs_indexFlags[adc->index] |= IFFree;
adc->dflags |= DFEntryMod;
- if (afs_WaitForCacheDrain) {
- if ((afs_blocksUsed - afs_blocksDiscarded) <=
- PERCENT(CM_CACHESIZEDRAINEDPCT, afs_cacheBlocks)) {
- afs_WaitForCacheDrain = 0;
- afs_osi_Wakeup(&afs_WaitForCacheDrain);
- }
- }
+ afs_WakeCacheWaitersIfDrained();
} /* afs_FreeDCache */
/*!
adc->dflags |= DFEntryMod;
afs_indexFlags[adc->index] |= IFDiscarded;
- if (afs_WaitForCacheDrain) {
- if ((afs_blocksUsed - afs_blocksDiscarded) <=
- PERCENT(CM_CACHESIZEDRAINEDPCT, afs_cacheBlocks)) {
- afs_WaitForCacheDrain = 0;
- afs_osi_Wakeup(&afs_WaitForCacheDrain);
- }
- }
-
+ afs_WakeCacheWaitersIfDrained();
} /*afs_DiscardDCache */
/**
(int)aslot, off);
}
- if (!entryok || !datavalid) {
+ if (indexvalid && !datavalid) {
+ /* we know that the given dslot does exist, but the data in it is not
+ * valid. this only occurs when we pull a dslot from the free or
+ * discard list, so be sure not to re-use the data; force invalidation.
+ */
+ entryok = 0;
+ }
+
+ if (!entryok) {
tdc->f.fid.Cell = 0;
tdc->f.fid.Fid.Volume = 0;
tdc->f.chunk = -1;
* is already being handled by the higher-level code.
*/
if ((avc->f.states & CSafeStore) == 0) {
- tb->code = 0;
+ tb->code_raw = tb->code_checkcode = 0;
tb->flags |= BUVALID;
if (tb->flags & BUWAIT) {
tb->flags &= ~BUWAIT;