From 1cee097b5bf44b0d8273712f0074b541f0f3f96e Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Fri, 28 Dec 2012 16:39:15 -0500 Subject: [PATCH] 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 Change-Id: If30026b5b2101559e704d0e1961effe14beb915f Reviewed-on: http://gerrit.openafs.org/8849 Tested-by: BuildBot Reviewed-by: Chas Williams - CONTRACTOR Reviewed-by: Derrick Brashear --- src/afs/afs_vcache.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 21c49f88c..c79309bd8 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -707,18 +707,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 (i++ > afs_vcount) { + } else if (i++ > limit) { refpanic("Found too many AFS vnodes on VLRU (VLRU cycle?)"); } else if (QNext(uq) != tq) { refpanic("VLRU inconsistent"); -- 2.39.5