If the cache entry never gets initialised, we want the garbage collector to be able to evict it. Otherwise if the upcall daemon fails to initialise the entry, we end up never expiring it.
Unified · Split
| @@ -209,9 +209,6 @@ static inline void cache_put(struct cache_head *h, struct cache_detail *cd) · 208 unmodified lines | ||
| 209 | 209 | |
| 210 | 210 | static inline bool cache_is_expired(struct cache_detail *detail, struct cache_head *h) |
| 211 | 211 | { |
| 212 | − if (!test_bit(CACHE_VALID, &h->flags)) | |
| 213 | − return false; | |
| 214 | − | |
| 215 | 212 | return (h->expiry_time < seconds_since_boot()) || |
| 216 | 213 | (detail->flush_time >= h->last_refresh); |
| 217 | 214 | } |
| @@ -64,13 +64,14 @@ static struct cache_head *sunrpc_cache_find_rcu(struct cache_detail *detail, · 63 unmodified lines | ||
| 64 | 64 | |
| 65 | 65 | rcu_read_lock(); |
| 66 | 66 | hlist_for_each_entry_rcu(tmp, head, cache_list) { |
| 67 | − if (detail->match(tmp, key)) { | |
| 68 | − if (cache_is_expired(detail, tmp)) | |
| 69 | − continue; | |
| 70 | − tmp = cache_get_rcu(tmp); | |
| 71 | − rcu_read_unlock(); | |
| 72 | − return tmp; | |
| 73 | − } | |
| 67 | + if (!detail->match(tmp, key)) | |
| 68 | + continue; | |
| 69 | + if (test_bit(CACHE_VALID, &tmp->flags) && | |
| 70 | + cache_is_expired(detail, tmp)) | |
| 71 | + continue; | |
| 72 | + tmp = cache_get_rcu(tmp); | |
| 73 | + rcu_read_unlock(); | |
| 74 | + return tmp; | |
| 74 | 75 | } |
| 75 | 76 | rcu_read_unlock(); |
| 76 | 77 | return NULL; |
| @@ -114,17 +115,18 @@ static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail, · 37 unmodified lines | ||
| 114 | 115 | /* check if entry appeared while we slept */ |
| 115 | 116 | hlist_for_each_entry_rcu(tmp, head, cache_list, |
| 116 | 117 | lockdep_is_held(&detail->hash_lock)) { |
| 117 | − if (detail->match(tmp, key)) { | |
| 118 | − if (cache_is_expired(detail, tmp)) { | |
| 119 | − sunrpc_begin_cache_remove_entry(tmp, detail); | |
| 120 | − freeme = tmp; | |
| 121 | − break; | |
| 122 | − } | |
| 123 | − cache_get(tmp); | |
| 124 | − spin_unlock(&detail->hash_lock); | |
| 125 | − cache_put(new, detail); | |
| 126 | − return tmp; | |
| 118 | + if (!detail->match(tmp, key)) | |
| 119 | + continue; | |
| 120 | + if (test_bit(CACHE_VALID, &tmp->flags) && | |
| 121 | + cache_is_expired(detail, tmp)) { | |
| 122 | + sunrpc_begin_cache_remove_entry(tmp, detail); | |
| 123 | + freeme = tmp; | |
| 124 | + break; | |
| 127 | 125 | } |
| 126 | + cache_get(tmp); | |
| 127 | + spin_unlock(&detail->hash_lock); | |
| 128 | + cache_put(new, detail); | |
| 129 | + return tmp; | |
| 128 | 130 | } |
| 129 | 131 | |
| 130 | 132 | hlist_add_head_rcu(&new->cache_list, head); |