From: Andrew Deason Date: Thu, 1 Nov 2012 21:33:31 +0000 (-0500) Subject: afs_FreeDiscardedDCache: Avoid assert on error X-Git-Tag: upstream/1.6.6_pre2^2~34 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=c8ffb8b9eefc8c2a0c6b41e3e29c0f03940a5fcf;p=packages%2Fo%2Fopenafs.git afs_FreeDiscardedDCache: Avoid assert on error Currently afs_FreeDiscardedDCache will assert if it cannot read in any discarded dcache entry to free. Return an error instead of asserting, so the caller can figure out what to do about the error. Adjust the callers to handle the error, or panic. afs_MaybeFreeDiscardedDCache still just panics anyway, as making it handle the error gracefully is beyond the scope of this commit, and is work for another day. This changes afs_FreeDiscardedDCache to return an int. Reviewed-on: http://gerrit.openafs.org/8406 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 866a9fbbdd89735ab76a70cb6d6523db2b98e4c9) Change-Id: I42a3be4938e5a43c394475653075f9e03a9e7975 Reviewed-on: http://gerrit.openafs.org/10357 Tested-by: BuildBot Reviewed-by: Andrew Deason Reviewed-by: Marc Dionne Reviewed-by: Mark Vitale Reviewed-by: Stephan Wiesand --- diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index 7aa537e6e..415b349f1 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -22,7 +22,7 @@ /* Forward declarations. */ static void afs_GetDownD(int anumber, int *aneedSpace, afs_int32 buckethint); -static void afs_FreeDiscardedDCache(void); +static int afs_FreeDiscardedDCache(void); static void afs_DiscardDCache(struct dcache *); static void afs_FreeDCache(struct dcache *); /* For split cache */ @@ -459,7 +459,16 @@ afs_CacheTruncateDaemon(void) */ while (afs_blocksDiscarded && !afs_WaitForCacheDrain && (afs_termState != AFSOP_STOP_TRUNCDAEMON)) { - afs_FreeDiscardedDCache(); + int code = afs_FreeDiscardedDCache(); + if (code) { + /* If we can't free any discarded dcache entries, that's okay. + * We're just doing this in the background; if someone needs + * discarded entries freed, they will try it themselves and/or + * signal us that the cache is too full. In any case, we'll + * try doing this again the next time we run through the loop. + */ + break; + } } /* See if we need to continue to run. Someone may have @@ -1096,8 +1105,11 @@ afs_GetDSlotFromList(afs_int32 *indexp) /*! * Free the next element on the list of discarded cache elements. + * + * Returns -1 if we encountered an error preventing us from freeing a + * discarded dcache, or 0 on success. */ -static void +static int afs_FreeDiscardedDCache(void) { struct dcache *tdc; @@ -1109,14 +1121,17 @@ afs_FreeDiscardedDCache(void) ObtainWriteLock(&afs_xdcache, 510); if (!afs_blocksDiscarded) { ReleaseWriteLock(&afs_xdcache); - return; + return 0; } /* * Get an entry from the list of discarded cache elements */ tdc = afs_GetDSlotFromList(&afs_discardDCList); - osi_Assert(tdc); + if (!tdc) { + ReleaseWriteLock(&afs_xdcache); + return -1; + } afs_discardDCCount--; size = ((tdc->f.chunkBytes + afs_fsfragsize) ^ afs_fsfragsize) >> 10; /* round up */ @@ -1145,6 +1160,8 @@ afs_FreeDiscardedDCache(void) ReleaseWriteLock(&tdc->lock); afs_PutDCache(tdc); ReleaseWriteLock(&afs_xdcache); + + return 0; } /*! @@ -1162,7 +1179,14 @@ afs_MaybeFreeDiscardedDCache(void) while (afs_blocksDiscarded && (afs_blocksUsed > PERCENT(CM_WAITFORDRAINPCT, afs_cacheBlocks))) { - afs_FreeDiscardedDCache(); + int code = afs_FreeDiscardedDCache(); + if (code) { + /* Callers depend on us to get the afs_blocksDiscarded count down. + * If we cannot do that, the callers can spin by calling us over + * and over. Panic for now until we can figure out something + * better. */ + osi_Panic("Error freeing discarded dcache"); + } } return 0; }