Commit 4013edea authored by NeilBrown's avatar NeilBrown Committed by Linus Torvalds

[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: default avatarNeil Brown <neilb@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f9ecc921
...@@ -208,7 +208,7 @@ int cache_check(struct cache_detail *detail, ...@@ -208,7 +208,7 @@ int cache_check(struct cache_detail *detail,
if (rv == -EAGAIN) if (rv == -EAGAIN)
cache_defer_req(rqstp, h); cache_defer_req(rqstp, h);
if (rv && h) if (rv)
detail->cache_put(h, detail); detail->cache_put(h, detail);
return rv; return rv;
} }
...@@ -223,8 +223,10 @@ void cache_fresh(struct cache_detail *detail, ...@@ -223,8 +223,10 @@ void cache_fresh(struct cache_detail *detail,
head->last_refresh = get_seconds(); head->last_refresh = get_seconds();
if (!test_and_set_bit(CACHE_VALID, &head->flags)) if (!test_and_set_bit(CACHE_VALID, &head->flags))
cache_revisit_request(head); 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); queue_loose(detail, head);
}
} }
/* /*
...@@ -551,7 +553,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item) ...@@ -551,7 +553,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
/* there was one too many */ /* there was one too many */
dreq->revisit(dreq, 1); dreq->revisit(dreq, 1);
} }
if (test_bit(CACHE_VALID, &item->flags)) { if (!test_bit(CACHE_PENDING, &item->flags)) {
/* must have just been validated... */ /* must have just been validated... */
cache_revisit_request(item); cache_revisit_request(item);
} }
...@@ -892,7 +894,7 @@ static void queue_loose(struct cache_detail *detail, struct cache_head *ch) ...@@ -892,7 +894,7 @@ static void queue_loose(struct cache_detail *detail, struct cache_head *ch)
if (cr->item != ch) if (cr->item != ch)
continue; continue;
if (cr->readers != 0) if (cr->readers != 0)
break; continue;
list_del(&cr->q.list); list_del(&cr->q.list);
spin_unlock(&queue_lock); spin_unlock(&queue_lock);
detail->cache_put(cr->item, detail); detail->cache_put(cr->item, detail);
...@@ -1180,8 +1182,8 @@ static int c_show(struct seq_file *m, void *p) ...@@ -1180,8 +1182,8 @@ static int c_show(struct seq_file *m, void *p)
return cd->cache_show(m, cd, NULL); return cd->cache_show(m, cd, NULL);
ifdebug(CACHE) ifdebug(CACHE)
seq_printf(m, "# expiry=%ld refcnt=%d\n", seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n",
cp->expiry_time, atomic_read(&cp->refcnt)); cp->expiry_time, atomic_read(&cp->refcnt), cp->flags);
cache_get(cp); cache_get(cp);
if (cache_check(cd, cp, NULL)) if (cache_check(cd, cp, NULL))
/* cache_check does a cache_put on failure */ /* cache_check does a cache_put on failure */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment