diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/cache.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 0d6002f26d82..a6c57334fa13 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 | ||
216 | static 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); |