diff options
Diffstat (limited to 'net/sunrpc/cache.c')
-rw-r--r-- | net/sunrpc/cache.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 824e8534e022..14274490f92e 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c | |||
@@ -530,6 +530,13 @@ static int cache_defer_req(struct cache_req *req, struct cache_head *item) | |||
530 | struct cache_deferred_req *dreq; | 530 | struct cache_deferred_req *dreq; |
531 | int hash = DFR_HASH(item); | 531 | int hash = DFR_HASH(item); |
532 | 532 | ||
533 | if (cache_defer_cnt >= DFR_MAX) { | ||
534 | /* too much in the cache, randomly drop this one, | ||
535 | * or continue and drop the oldest below | ||
536 | */ | ||
537 | if (net_random()&1) | ||
538 | return -ETIMEDOUT; | ||
539 | } | ||
533 | dreq = req->defer(req); | 540 | dreq = req->defer(req); |
534 | if (dreq == NULL) | 541 | if (dreq == NULL) |
535 | return -ETIMEDOUT; | 542 | return -ETIMEDOUT; |
@@ -548,17 +555,8 @@ static int cache_defer_req(struct cache_req *req, struct cache_head *item) | |||
548 | /* it is in, now maybe clean up */ | 555 | /* it is in, now maybe clean up */ |
549 | dreq = NULL; | 556 | dreq = NULL; |
550 | if (++cache_defer_cnt > DFR_MAX) { | 557 | if (++cache_defer_cnt > DFR_MAX) { |
551 | /* too much in the cache, randomly drop | 558 | dreq = list_entry(cache_defer_list.prev, |
552 | * first or last | 559 | struct cache_deferred_req, recent); |
553 | */ | ||
554 | if (net_random()&1) | ||
555 | dreq = list_entry(cache_defer_list.next, | ||
556 | struct cache_deferred_req, | ||
557 | recent); | ||
558 | else | ||
559 | dreq = list_entry(cache_defer_list.prev, | ||
560 | struct cache_deferred_req, | ||
561 | recent); | ||
562 | list_del(&dreq->recent); | 560 | list_del(&dreq->recent); |
563 | list_del(&dreq->hash); | 561 | list_del(&dreq->hash); |
564 | cache_defer_cnt--; | 562 | cache_defer_cnt--; |