History

SUNRPC/cache: Allow garbage collection of invalid cache entries

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.

Trond Myklebust committed 6 years ago

Commit 277f27e1 parent 65286b82 files · +19 −20Browse files

Unified · Split

2 files
  1. include/linux/sunrpc/cache.h +0 −3
  2. net/sunrpc/cache.c +19 −17
include/linux/sunrpc/cache.h+0−3
@@ -209,9 +209,6 @@ static inline void cache_put(struct cache_head *h, struct cache_detail *cd) · 208 unmodified lines
209 209
210static inline bool cache_is_expired(struct cache_detail *detail, struct cache_head *h)210static 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 return (h->expiry_time < seconds_since_boot()) ||212 return (h->expiry_time < seconds_since_boot()) ||
216 (detail->flush_time >= h->last_refresh);213 (detail->flush_time >= h->last_refresh);
217}214}
net/sunrpc/cache.c+19−17
@@ -64,13 +64,14 @@ static struct cache_head *sunrpc_cache_find_rcu(struct cache_detail *detail, · 63 unmodified lines
64 64
65 rcu_read_lock();65 rcu_read_lock();
66 hlist_for_each_entry_rcu(tmp, head, cache_list) {66 hlist_for_each_entry_rcu(tmp, head, cache_list) {
67 if (detail->match(tmp, key)) {67 if (!detail->match(tmp, key))
68 if (cache_is_expired(detail, tmp))68 continue;
69 continue;69 if (test_bit(CACHE_VALID, &tmp->flags) &&
70 tmp = cache_get_rcu(tmp);70 cache_is_expired(detail, tmp))
71 rcu_read_unlock();71 continue;
72 return tmp;72 tmp = cache_get_rcu(tmp);
73 }73 rcu_read_unlock();
74 return tmp;
74 }75 }
75 rcu_read_unlock();76 rcu_read_unlock();
76 return NULL;77 return NULL;
@@ -114,17 +115,18 @@ static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail, · 37 unmodified lines
114 /* check if entry appeared while we slept */115 /* check if entry appeared while we slept */
115 hlist_for_each_entry_rcu(tmp, head, cache_list,116 hlist_for_each_entry_rcu(tmp, head, cache_list,
116 lockdep_is_held(&detail->hash_lock)) {117 lockdep_is_held(&detail->hash_lock)) {
117 if (detail->match(tmp, key)) {118 if (!detail->match(tmp, key))
118 if (cache_is_expired(detail, tmp)) {119 continue;
119 sunrpc_begin_cache_remove_entry(tmp, detail);120 if (test_bit(CACHE_VALID, &tmp->flags) &&
120 freeme = tmp;121 cache_is_expired(detail, tmp)) {
121 break;122 sunrpc_begin_cache_remove_entry(tmp, detail);
122 }123 freeme = tmp;
123 cache_get(tmp);124 break;
124 spin_unlock(&detail->hash_lock);
125 cache_put(new, detail);
126 return tmp;
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 hlist_add_head_rcu(&new->cache_list, head);132 hlist_add_head_rcu(&new->cache_list, head);