afs: Return raw code from background daemons
[openafs.git] / src / afs / afs_dcache.c
index 8833c39..dd75e2c 100644 (file)
@@ -396,6 +396,27 @@ static struct CTD_stats {
 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
@@ -416,7 +437,7 @@ afs_CacheTruncateDaemon(void)
     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++) {
@@ -431,14 +452,15 @@ afs_CacheTruncateDaemon(void)
                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);
 
@@ -987,14 +1009,6 @@ afs_FlushDCache(struct dcache *adc)
     } 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 */
 
 
@@ -1019,13 +1033,7 @@ afs_FreeDCache(struct dcache *adc)
     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 */
 
 /*!
@@ -1065,14 +1073,7 @@ afs_DiscardDCache(struct dcache *adc)
     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 */
 
 /**
@@ -2899,7 +2900,15 @@ afs_UFSGetDSlot(afs_int32 aslot, int indexvalid, int datavalid)
                  (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;
@@ -3035,7 +3044,7 @@ afs_wakeup(struct vcache *avc)
             * 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;