summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-03-27 01:15:07 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-27 08:44:42 -0800
commit4013edea9a0b6cdcb1fdf5d4011e47e068fd6efb (patch)
tree19ea135919b899ba11552c155c4b403ed38204da
parentf9ecc921b5b5e135050e7f22fef873c249aee3fc (diff)
[PATCH] knfsd: An assortment of little fixes to the sunrpc cache code
- in cache_check, h must be non-NULL as it has been de-referenced, so don't bother checking for NULL. - When a cache-item is updated, we need to call cache_revisit_request to see if there is a pending request waiting for that item. We were using a transition to CACHE_VALID to see if that was needed, however that is wrong as an expired entry will still be marked 'valid' (as the data is valid and will need to be released). So instead use an off transition for CACHE_PENDING which is exactly the right thing to test. - Add a little bit more debugging info. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--net/sunrpc/cache.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 4449dc52edf..b242f491cea 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -208,7 +208,7 @@ int cache_check(struct cache_detail *detail,
if (rv == -EAGAIN)
cache_defer_req(rqstp, h);
- if (rv && h)
+ if (rv)
detail->cache_put(h, detail);
return rv;
}
@@ -223,8 +223,10 @@ void cache_fresh(struct cache_detail *detail,
head->last_refresh = get_seconds();
if (!test_and_set_bit(CACHE_VALID, &head->flags))
cache_revisit_request(head);
- if (test_and_clear_bit(CACHE_PENDING, &head->flags))
+ if (test_and_clear_bit(CACHE_PENDING, &head->flags)) {
+ cache_revisit_request(head);
queue_loose(detail, head);
+ }
}
/*
@@ -551,7 +553,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
/* there was one too many */
dreq->revisit(dreq, 1);
}
- if (test_bit(CACHE_VALID, &item->flags)) {
+ if (!test_bit(CACHE_PENDING, &item->flags)) {
/* must have just been validated... */
cache_revisit_request(item);
}
@@ -892,7 +894,7 @@ static void queue_loose(struct cache_detail *detail, struct cache_head *ch)
if (cr->item != ch)
continue;
if (cr->readers != 0)
- break;
+ continue;
list_del(&cr->q.list);
spin_unlock(&queue_lock);
detail->cache_put(cr->item, detail);
@@ -1180,8 +1182,8 @@ static int c_show(struct seq_file *m, void *p)
return cd->cache_show(m, cd, NULL);
ifdebug(CACHE)
- seq_printf(m, "# expiry=%ld refcnt=%d\n",
- cp->expiry_time, atomic_read(&cp->refcnt));
+ seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n",
+ cp->expiry_time, atomic_read(&cp->refcnt), cp->flags);
cache_get(cp);
if (cache_check(cd, cp, NULL))
/* cache_check does a cache_put on failure */