aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/cache.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 0d6002f26d8..a6c57334fa1 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -213,6 +213,23 @@ static inline int cache_is_valid(struct cache_detail *detail, struct cache_head
213 } 213 }
214} 214}
215 215
216static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h)
217{
218 int rv;
219
220 write_lock(&detail->hash_lock);
221 rv = cache_is_valid(detail, h);
222 if (rv != -EAGAIN) {
223 write_unlock(&detail->hash_lock);
224 return rv;
225 }
226 set_bit(CACHE_NEGATIVE, &h->flags);
227 cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
228 write_unlock(&detail->hash_lock);
229 cache_fresh_unlocked(h, detail);
230 return -ENOENT;
231}
232
216/* 233/*
217 * This is the generic cache management routine for all 234 * This is the generic cache management routine for all
218 * the authentication caches. 235 * the authentication caches.
@@ -251,14 +268,8 @@ int cache_check(struct cache_detail *detail,
251 case -EINVAL: 268 case -EINVAL:
252 clear_bit(CACHE_PENDING, &h->flags); 269 clear_bit(CACHE_PENDING, &h->flags);
253 cache_revisit_request(h); 270 cache_revisit_request(h);
254 if (rv == -EAGAIN) { 271 rv = try_to_negate_entry(detail, h);
255 set_bit(CACHE_NEGATIVE, &h->flags);
256 cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
257 cache_fresh_unlocked(h, detail);
258 rv = -ENOENT;
259 }
260 break; 272 break;
261
262 case -EAGAIN: 273 case -EAGAIN:
263 clear_bit(CACHE_PENDING, &h->flags); 274 clear_bit(CACHE_PENDING, &h->flags);
264 cache_revisit_request(h); 275 cache_revisit_request(h);