aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/cache.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-06-12 22:53:42 -0400
committerJ. Bruce Fields <bfields@redhat.com>2013-07-01 17:53:28 -0400
commit2a1c7f53fd31e46f51780b61eb99fffef4c3c5a6 (patch)
tree2c10acb62a365dfabd116c5c70e7c528a4f0e7e9 /net/sunrpc/cache.c
parentf9e1aedc6c79f18bb56caa3735b94217c4ec1e0c (diff)
sunrpc/cache: use cache_fresh_unlocked consistently and correctly.
cache_fresh_unlocked() is called when a cache entry has been updated and ensures that if there were any pending upcalls, they are cleared. So every time we update a cache entry, we should call this, and this should be the only way that we try to clear pending calls (that sort of uniformity makes code sooo much easier to read). try_to_negate_entry() will (possibly) mark an entry as negative. If it doesn't, it is because the entry already is VALID. So the entry will be valid on exit, so it is appropriate to call cache_fresh_unlocked(). So tidy up try_to_negate_entry() to do that, and remove partial open-coded cache_fresh_unlocked() from the one call-site of try_to_negate_entry(). In the other branch of the 'switch(cache_make_upcall())', we again have a partial open-coded version of cache_fresh_unlocked(). Replace that with a real call. And again in cache_clean(), use a real call to cache_fresh_unlocked(). These call sites might previously have called cache_revisit_request() if CACHE_PENDING wasn't set. This is never necessary because cache_revisit_request() can only do anything if the item is in the cache_defer_hash, However any time that an item is added to the cache_defer_hash (setup_deferral), the code immediately tests CACHE_PENDING, and removes the entry again if it is clear. So all other places we only need to 'cache_revisit_request' if we've just cleared CACHE_PENDING. Reported-by: Bodo Stroesser <bstroesser@ts.fujitsu.com> Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/sunrpc/cache.c')
-rw-r--r--net/sunrpc/cache.c20
1 files changed, 7 insertions, 13 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 8e964ae8d7b5..29c463396a2d 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -228,15 +228,14 @@ static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h
228 228
229 write_lock(&detail->hash_lock); 229 write_lock(&detail->hash_lock);
230 rv = cache_is_valid(h); 230 rv = cache_is_valid(h);
231 if (rv != -EAGAIN) { 231 if (rv == -EAGAIN) {
232 write_unlock(&detail->hash_lock); 232 set_bit(CACHE_NEGATIVE, &h->flags);
233 return rv; 233 cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
234 rv = -ENOENT;
234 } 235 }
235 set_bit(CACHE_NEGATIVE, &h->flags);
236 cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
237 write_unlock(&detail->hash_lock); 236 write_unlock(&detail->hash_lock);
238 cache_fresh_unlocked(h, detail); 237 cache_fresh_unlocked(h, detail);
239 return -ENOENT; 238 return rv;
240} 239}
241 240
242/* 241/*
@@ -275,13 +274,10 @@ int cache_check(struct cache_detail *detail,
275 if (!test_and_set_bit(CACHE_PENDING, &h->flags)) { 274 if (!test_and_set_bit(CACHE_PENDING, &h->flags)) {
276 switch (cache_make_upcall(detail, h)) { 275 switch (cache_make_upcall(detail, h)) {
277 case -EINVAL: 276 case -EINVAL:
278 clear_bit(CACHE_PENDING, &h->flags);
279 cache_revisit_request(h);
280 rv = try_to_negate_entry(detail, h); 277 rv = try_to_negate_entry(detail, h);
281 break; 278 break;
282 case -EAGAIN: 279 case -EAGAIN:
283 clear_bit(CACHE_PENDING, &h->flags); 280 cache_fresh_unlocked(h, detail);
284 cache_revisit_request(h);
285 break; 281 break;
286 } 282 }
287 } 283 }
@@ -457,9 +453,7 @@ static int cache_clean(void)
457 current_index ++; 453 current_index ++;
458 spin_unlock(&cache_list_lock); 454 spin_unlock(&cache_list_lock);
459 if (ch) { 455 if (ch) {
460 if (test_and_clear_bit(CACHE_PENDING, &ch->flags)) 456 cache_fresh_unlocked(ch, d);
461 cache_dequeue(current_detail, ch);
462 cache_revisit_request(ch);
463 cache_put(ch, d); 457 cache_put(ch, d);
464 } 458 }
465 } else 459 } else