aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/cache.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 9826c5ceb995..3e1ef8bf4dc2 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -59,7 +59,7 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
59 struct cache_head *key, int hash) 59 struct cache_head *key, int hash)
60{ 60{
61 struct cache_head **head, **hp; 61 struct cache_head **head, **hp;
62 struct cache_head *new = NULL; 62 struct cache_head *new = NULL, *freeme = NULL;
63 63
64 head = &detail->hash_table[hash]; 64 head = &detail->hash_table[hash];
65 65
@@ -68,6 +68,9 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
68 for (hp=head; *hp != NULL ; hp = &(*hp)->next) { 68 for (hp=head; *hp != NULL ; hp = &(*hp)->next) {
69 struct cache_head *tmp = *hp; 69 struct cache_head *tmp = *hp;
70 if (detail->match(tmp, key)) { 70 if (detail->match(tmp, key)) {
71 if (cache_is_expired(detail, tmp))
72 /* This entry is expired, we will discard it. */
73 break;
71 cache_get(tmp); 74 cache_get(tmp);
72 read_unlock(&detail->hash_lock); 75 read_unlock(&detail->hash_lock);
73 return tmp; 76 return tmp;
@@ -92,6 +95,13 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
92 for (hp=head; *hp != NULL ; hp = &(*hp)->next) { 95 for (hp=head; *hp != NULL ; hp = &(*hp)->next) {
93 struct cache_head *tmp = *hp; 96 struct cache_head *tmp = *hp;
94 if (detail->match(tmp, key)) { 97 if (detail->match(tmp, key)) {
98 if (cache_is_expired(detail, tmp)) {
99 *hp = tmp->next;
100 tmp->next = NULL;
101 detail->entries --;
102 freeme = tmp;
103 break;
104 }
95 cache_get(tmp); 105 cache_get(tmp);
96 write_unlock(&detail->hash_lock); 106 write_unlock(&detail->hash_lock);
97 cache_put(new, detail); 107 cache_put(new, detail);
@@ -104,6 +114,8 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
104 cache_get(new); 114 cache_get(new);
105 write_unlock(&detail->hash_lock); 115 write_unlock(&detail->hash_lock);
106 116
117 if (freeme)
118 cache_put(freeme, detail);
107 return new; 119 return new;
108} 120}
109EXPORT_SYMBOL_GPL(sunrpc_cache_lookup); 121EXPORT_SYMBOL_GPL(sunrpc_cache_lookup);
@@ -189,8 +201,7 @@ static int cache_make_upcall(struct cache_detail *cd, struct cache_head *h)
189 201
190static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h) 202static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h)
191{ 203{
192 if (!test_bit(CACHE_VALID, &h->flags) || 204 if (!test_bit(CACHE_VALID, &h->flags))
193 cache_is_expired(detail, h))
194 return -EAGAIN; 205 return -EAGAIN;
195 else { 206 else {
196 /* entry is valid */ 207 /* entry is valid */