aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-03-27 04:15:07 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-27 11:44:42 -0500
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 4449dc52edf5..b242f491cea9 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -208,7 +208,7 @@ int cache_check(struct cache_detail *detail,
208 if (rv == -EAGAIN) 208 if (rv == -EAGAIN)
209 cache_defer_req(rqstp, h); 209 cache_defer_req(rqstp, h);
210 210
211 if (rv && h) 211 if (rv)
212 detail->cache_put(h, detail); 212 detail->cache_put(h, detail);
213 return rv; 213 return rv;
214} 214}
@@ -223,8 +223,10 @@ void cache_fresh(struct cache_detail *detail,
223 head->last_refresh = get_seconds(); 223 head->last_refresh = get_seconds();
224 if (!test_and_set_bit(CACHE_VALID, &head->flags)) 224 if (!test_and_set_bit(CACHE_VALID, &head->flags))
225 cache_revisit_request(head); 225 cache_revisit_request(head);
226 if (test_and_clear_bit(CACHE_PENDING, &head->flags)) 226 if (test_and_clear_bit(CACHE_PENDING, &head->flags)) {
227 cache_revisit_request(head);
227 queue_loose(detail, head); 228 queue_loose(detail, head);
229 }
228} 230}
229 231
230/* 232/*
@@ -551,7 +553,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
551 /* there was one too many */ 553 /* there was one too many */
552 dreq->revisit(dreq, 1); 554 dreq->revisit(dreq, 1);
553 } 555 }
554 if (test_bit(CACHE_VALID, &item->flags)) { 556 if (!test_bit(CACHE_PENDING, &item->flags)) {
555 /* must have just been validated... */ 557 /* must have just been validated... */
556 cache_revisit_request(item); 558 cache_revisit_request(item);
557 } 559 }
@@ -892,7 +894,7 @@ static void queue_loose(struct cache_detail *detail, struct cache_head *ch)
892 if (cr->item != ch) 894 if (cr->item != ch)
893 continue; 895 continue;
894 if (cr->readers != 0) 896 if (cr->readers != 0)
895 break; 897 continue;
896 list_del(&cr->q.list); 898 list_del(&cr->q.list);
897 spin_unlock(&queue_lock); 899 spin_unlock(&queue_lock);
898 detail->cache_put(cr->item, detail); 900 detail->cache_put(cr->item, detail);
@@ -1180,8 +1182,8 @@ static int c_show(struct seq_file *m, void *p)
1180 return cd->cache_show(m, cd, NULL); 1182 return cd->cache_show(m, cd, NULL);
1181 1183
1182 ifdebug(CACHE) 1184 ifdebug(CACHE)
1183 seq_printf(m, "# expiry=%ld refcnt=%d\n", 1185 seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n",
1184 cp->expiry_time, atomic_read(&cp->refcnt)); 1186 cp->expiry_time, atomic_read(&cp->refcnt), cp->flags);
1185 cache_get(cp); 1187 cache_get(cp);
1186 if (cache_check(cd, cp, NULL)) 1188 if (cache_check(cd, cp, NULL))
1187 /* cache_check does a cache_put on failure */ 1189 /* cache_check does a cache_put on failure */