[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>
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 4449dc5..b242f49 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -208,7 +208,7 @@
if (rv == -EAGAIN)
cache_defer_req(rqstp, h);
- if (rv && h)
+ if (rv)
detail->cache_put(h, detail);
return rv;
}
@@ -223,8 +223,10 @@
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 @@
/* 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 @@
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 @@
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 */