sunrpc/cache: make sure deferred requests eventually get revisited.
authorNeilBrown <neilb@suse.de>
Tue, 4 Aug 2009 05:22:38 +0000 (15:22 +1000)
committerJ. Bruce Fields <bfields@citi.umich.edu>
Tue, 4 Aug 2009 15:03:01 +0000 (11:03 -0400)
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>
net/sunrpc/cache.c

index d19c07583f8fbf59ef3fd4f5f9797fdbe0228b94..44f45166378a5f1b6be3d7994951882355bf6976 100644 (file)
@@ -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);