From: Andrew Deason Date: Fri, 28 Dec 2012 21:39:15 +0000 (-0500) Subject: afs: Avoid unnecessary panic in ShakeLooseVCaches X-Git-Tag: upstream/1.6.2_pre3^2~7 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=075893f250beaf3bb22cebc5fb1f936557cce50c;p=packages%2Fo%2Fopenafs.git afs: Avoid unnecessary panic in ShakeLooseVCaches afs_vcount can change as we traverse the loop. If we successfully evict something from the cache, afs_vcount goes down, but our loop variable 'i' stays incremented. For example, if afs_vcount was 100 at the start of the loop and we kicked out 50 things, by the time we traverse the entire VLRU, we could have iterated over the loop 100 times, but afs_vcount would still be just at 50. So, remember what afs_vcount was at the start of the loop, and use that for our loop limit. Note that vcaches cannot be added to the VLRU during the execution of this loop, since we're just kicking stuff out. And nobody else can modify the VLRU but us, since we're holding afs_xvcache, and if we drop afs_xvcache, we restart the whole eviction process. The bug here was introduced by commit bc6dd950, but usually did not affect Linux until commit 696db866. FIXES 131553 Reviewed-on: http://gerrit.openafs.org/8849 Tested-by: BuildBot Reviewed-by: Chas Williams - CONTRACTOR Reviewed-by: Derrick Brashear (cherry picked from commit 1cee097b5bf44b0d8273712f0074b541f0f3f96e) Change-Id: I1bdbe41980e03522905217e55f745a96fb2bdc2d Reviewed-on: http://gerrit.openafs.org/8867 Tested-by: BuildBot Reviewed-by: Andrew Deason Reviewed-by: Paul Smeddle Reviewed-by: Stephan Wiesand --- diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index c1f0d5bc2..6f0bf50e7 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -661,18 +661,20 @@ afs_ShakeLooseVCaches(afs_int32 anumber) struct vcache *tvc; struct afs_q *tq, *uq; int fv_slept, defersleep = 0; + int limit; afs_int32 target = anumber; loop = 0; retry: i = 0; + limit = afs_vcount; for (tq = VLRU.prev; tq != &VLRU && anumber > 0; tq = uq) { tvc = QTOV(tq); uq = QPrev(tq); if (tvc->f.states & CVFlushed) { refpanic("CVFlushed on VLRU"); - } else if (!afsd_dynamic_vcaches && i++ > afs_vcount) { + } else if (!afsd_dynamic_vcaches && i++ > limit) { refpanic("Found too many AFS vnodes on VLRU (VLRU cycle?)"); } else if (QNext(uq) != tq) { refpanic("VLRU inconsistent");