]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
afs: Traverse discard/free dslot list if errors
authorAndrew Deason <adeason@sinenomine.net>
Thu, 1 Nov 2012 18:41:06 +0000 (13:41 -0500)
committerStephan Wiesand <stephan.wiesand@desy.de>
Wed, 30 Oct 2013 18:33:04 +0000 (11:33 -0700)
Currently, when we pull a dslot off of the discard or free list, we
just try to get the first entry from the list, and panic if we cannot
get it. Instead, traverse through the whole list, trying to find an
entry we can successfully get. This introduces the helper function
afs_GetDSlotFromList to do this traversal.

This does not yet address the case where we cannot get any entry on
the relevant list.

Reviewed-on: http://gerrit.openafs.org/8376
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@your-file-system.com>
(cherry picked from commit 336939179721d79a6798614ff747dd06701e3edc)

Change-Id: I12d8cfbe7d1fe7bbe50b49bcee34a8a5dced1569
Reviewed-on: http://gerrit.openafs.org/10354
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Marc Dionne <marc.c.dionne@gmail.com>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
src/afs/afs_dcache.c

index 8f3d5d627fee26f2811f947d3b346d8745ab5a6b..593473c7da2101efa9a7b077332210c712a41cd5 100644 (file)
@@ -1066,6 +1066,34 @@ afs_DiscardDCache(struct dcache *adc)
 
 }                              /*afs_DiscardDCache */
 
+/**
+ * Get a dcache entry from the discard or free list
+ *
+ * @param[in] indexp  A pointer to the head of the dcache free list or discard
+ *                    list (afs_freeDCList, or afs_discardDCList)
+ *
+ * @return A dcache from that list, or NULL if none could be retrieved.
+ *
+ * @pre afs_xdcache is write-locked
+ */
+static struct dcache *
+afs_GetDSlotFromList(afs_int32 *indexp)
+{
+    struct dcache *tdc;
+
+    for ( ; *indexp != NULLIDX; indexp = &afs_dvnextTbl[*indexp]) {
+       tdc = afs_GetUnusedDSlot(*indexp);
+       if (tdc) {
+           osi_Assert(tdc->refCount == 1);
+           ReleaseReadLock(&tdc->tlock);
+           *indexp = afs_dvnextTbl[tdc->index];
+           afs_dvnextTbl[tdc->index] = NULLIDX;
+           return tdc;
+       }
+    }
+    return NULL;
+}
+
 /*!
  * Free the next element on the list of discarded cache elements.
  */
@@ -1087,13 +1115,9 @@ afs_FreeDiscardedDCache(void)
     /*
      * Get an entry from the list of discarded cache elements
      */
-    tdc = afs_GetUnusedDSlot(afs_discardDCList);
+    tdc = afs_GetDSlotFromList(&afs_discardDCList);
     osi_Assert(tdc);
-    osi_Assert(tdc->refCount == 1);
-    ReleaseReadLock(&tdc->tlock);
 
-    afs_discardDCList = afs_dvnextTbl[tdc->index];
-    afs_dvnextTbl[tdc->index] = NULLIDX;
     afs_discardDCCount--;
     size = ((tdc->f.chunkBytes + afs_fsfragsize) ^ afs_fsfragsize) >> 10;      /* round up */
     afs_blocksDiscarded -= size;
@@ -1516,22 +1540,16 @@ afs_AllocDCache(struct vcache *avc, afs_int32 chunk, afs_int32 lock,
     if (afs_discardDCList == NULLIDX
        || ((lock & 2) && afs_freeDCList != NULLIDX)) {
 
-       afs_indexFlags[afs_freeDCList] &= ~IFFree;
-       tdc = afs_GetUnusedDSlot(afs_freeDCList);
+       tdc = afs_GetDSlotFromList(&afs_freeDCList);
        osi_Assert(tdc);
-       osi_Assert(tdc->refCount == 1);
-       ReleaseReadLock(&tdc->tlock);
+       afs_indexFlags[tdc->index] &= ~IFFree;
        ObtainWriteLock(&tdc->lock, 604);
-       afs_freeDCList = afs_dvnextTbl[tdc->index];
        afs_freeDCCount--;
     } else {
-       afs_indexFlags[afs_discardDCList] &= ~IFDiscarded;
-       tdc = afs_GetUnusedDSlot(afs_discardDCList);
+       tdc = afs_GetDSlotFromList(&afs_discardDCList);
        osi_Assert(tdc);
-       osi_Assert(tdc->refCount == 1);
-       ReleaseReadLock(&tdc->tlock);
+       afs_indexFlags[tdc->index] &= ~IFDiscarded;
        ObtainWriteLock(&tdc->lock, 605);
-       afs_discardDCList = afs_dvnextTbl[tdc->index];
        afs_discardDCCount--;
        size =
            ((tdc->f.chunkBytes +