summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-08-04 15:22:38 +1000
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-08-04 11:03:01 -0400
commit5c4d26390341732a8d614141a4cf4663610a1698 (patch)
tree1361af921aadc75c1a1fa1a23eb83292dcad8130 /net
parentf866a8194f7cbabb9135b98b9ac7d26237b88367 (diff)
downloadlinux-stable-5c4d26390341732a8d614141a4cf4663610a1698.tar.gz
linux-stable-5c4d26390341732a8d614141a4cf4663610a1698.tar.bz2
linux-stable-5c4d26390341732a8d614141a4cf4663610a1698.zip
sunrpc/cache: make sure deferred requests eventually get revisited.
While deferred requests normally get revisited quite quickly, it is possible for a request to remain in the deferral queue when the cache item is discarded. We can easily make sure that doesn't happen by calling cache_revisit_request just before the final 'put'. Also there is a small chance that a race would cause one thread to defer a request against a cache item while another thread is failing to queue an upcall for that item. So when the upcall fails, make sure to revisit all deferred requests. Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/cache.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index d19c07583f8f..44f45166378a 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -221,6 +221,7 @@ int cache_check(struct cache_detail *detail,
switch (cache_make_upcall(detail, h)) {
case -EINVAL:
clear_bit(CACHE_PENDING, &h->flags);
+ cache_revisit_request(h);
if (rv == -EAGAIN) {
set_bit(CACHE_NEGATIVE, &h->flags);
cache_fresh_unlocked(h, detail,
@@ -473,8 +474,10 @@ static int cache_clean(void)
if (!ch)
current_index ++;
spin_unlock(&cache_list_lock);
- if (ch)
+ if (ch) {
+ cache_revisit_request(ch);
cache_put(ch, d);
+ }
} else
spin_unlock(&cache_list_lock);