aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-10-07 00:29:46 -0400
committerJ. Bruce Fields <bfields@redhat.com>2010-10-11 19:30:27 -0400
commitd29068c431599fa96729556846562eb18429092d (patch)
tree6330502e1a6247de1cb785fe44ab599662cb369c /net/sunrpc
parent33515142156efc9ab5dbfe93ff8d4765559dc987 (diff)
sunrpc: Simplify cache_defer_req and related functions.
The return value from cache_defer_req is somewhat confusing. Various different error codes are returned, but the single caller is only interested in success or failure. In fact it can measure this success or failure itself by checking CACHE_PENDING, which makes the point of the code more explicit. So change cache_defer_req to return 'void' and test CACHE_PENDING after it completes, to see if the request was actually deferred or not. Similarly setup_deferral and cache_wait_req don't need a return value, so make them void and remove some code. The call to cache_revisit_request (to guard against a race) is only needed for the second call to setup_deferral, so move it out of setup_deferral to after that second call. With the first call the race is handled differently (by explicitly calling 'wait_for_completion'). Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/cache.c58
1 files changed, 22 insertions, 36 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 1e72cc955931..49115b107fbd 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -38,7 +38,7 @@
38 38
39#define RPCDBG_FACILITY RPCDBG_CACHE 39#define RPCDBG_FACILITY RPCDBG_CACHE
40 40
41static int cache_defer_req(struct cache_req *req, struct cache_head *item); 41static void cache_defer_req(struct cache_req *req, struct cache_head *item);
42static void cache_revisit_request(struct cache_head *item); 42static void cache_revisit_request(struct cache_head *item);
43 43
44static void cache_init(struct cache_head *h) 44static void cache_init(struct cache_head *h)
@@ -269,7 +269,8 @@ int cache_check(struct cache_detail *detail,
269 } 269 }
270 270
271 if (rv == -EAGAIN) { 271 if (rv == -EAGAIN) {
272 if (cache_defer_req(rqstp, h) < 0) { 272 cache_defer_req(rqstp, h);
273 if (!test_bit(CACHE_PENDING, &h->flags)) {
273 /* Request is not deferred */ 274 /* Request is not deferred */
274 rv = cache_is_valid(detail, h); 275 rv = cache_is_valid(detail, h);
275 if (rv == -EAGAIN) 276 if (rv == -EAGAIN)
@@ -525,7 +526,7 @@ static void __hash_deferred_req(struct cache_deferred_req *dreq, struct cache_he
525 hlist_add_head(&dreq->hash, &cache_defer_hash[hash]); 526 hlist_add_head(&dreq->hash, &cache_defer_hash[hash]);
526} 527}
527 528
528static int setup_deferral(struct cache_deferred_req *dreq, struct cache_head *item) 529static void setup_deferral(struct cache_deferred_req *dreq, struct cache_head *item)
529{ 530{
530 struct cache_deferred_req *discard; 531 struct cache_deferred_req *discard;
531 532
@@ -547,13 +548,6 @@ static int setup_deferral(struct cache_deferred_req *dreq, struct cache_head *it
547 if (discard) 548 if (discard)
548 /* there was one too many */ 549 /* there was one too many */
549 discard->revisit(discard, 1); 550 discard->revisit(discard, 1);
550
551 if (!test_bit(CACHE_PENDING, &item->flags)) {
552 /* must have just been validated... */
553 cache_revisit_request(item);
554 return -EAGAIN;
555 }
556 return 0;
557} 551}
558 552
559struct thread_deferred_req { 553struct thread_deferred_req {
@@ -568,18 +562,17 @@ static void cache_restart_thread(struct cache_deferred_req *dreq, int too_many)
568 complete(&dr->completion); 562 complete(&dr->completion);
569} 563}
570 564
571static int cache_wait_req(struct cache_req *req, struct cache_head *item) 565static void cache_wait_req(struct cache_req *req, struct cache_head *item)
572{ 566{
573 struct thread_deferred_req sleeper; 567 struct thread_deferred_req sleeper;
574 struct cache_deferred_req *dreq = &sleeper.handle; 568 struct cache_deferred_req *dreq = &sleeper.handle;
575 int ret;
576 569
577 sleeper.completion = COMPLETION_INITIALIZER_ONSTACK(sleeper.completion); 570 sleeper.completion = COMPLETION_INITIALIZER_ONSTACK(sleeper.completion);
578 dreq->revisit = cache_restart_thread; 571 dreq->revisit = cache_restart_thread;
579 572
580 ret = setup_deferral(dreq, item); 573 setup_deferral(dreq, item);
581 574
582 if (ret || 575 if (!test_bit(CACHE_PENDING, &item->flags) ||
583 wait_for_completion_interruptible_timeout( 576 wait_for_completion_interruptible_timeout(
584 &sleeper.completion, req->thread_wait) <= 0) { 577 &sleeper.completion, req->thread_wait) <= 0) {
585 /* The completion wasn't completed, so we need 578 /* The completion wasn't completed, so we need
@@ -599,41 +592,34 @@ static int cache_wait_req(struct cache_req *req, struct cache_head *item)
599 wait_for_completion(&sleeper.completion); 592 wait_for_completion(&sleeper.completion);
600 } 593 }
601 } 594 }
602 if (test_bit(CACHE_PENDING, &item->flags)) {
603 /* item is still pending, try request
604 * deferral
605 */
606 return -ETIMEDOUT;
607 }
608 /* only return success if we actually deferred the
609 * request. In this case we waited until it was
610 * answered so no deferral has happened - rather
611 * an answer already exists.
612 */
613 return -EEXIST;
614} 595}
615 596
616static int cache_defer_req(struct cache_req *req, struct cache_head *item) 597static void cache_defer_req(struct cache_req *req, struct cache_head *item)
617{ 598{
618 struct cache_deferred_req *dreq; 599 struct cache_deferred_req *dreq;
619 int ret;
620 600
621 if (cache_defer_cnt >= DFR_MAX) { 601 if (cache_defer_cnt >= DFR_MAX)
622 /* too much in the cache, randomly drop this one, 602 /* too much in the cache, randomly drop this one,
623 * or continue and drop the oldest 603 * or continue and drop the oldest
624 */ 604 */
625 if (net_random()&1) 605 if (net_random()&1)
626 return -ENOMEM; 606 return;
627 } 607
608
628 if (req->thread_wait) { 609 if (req->thread_wait) {
629 ret = cache_wait_req(req, item); 610 cache_wait_req(req, item);
630 if (ret != -ETIMEDOUT) 611 if (!test_bit(CACHE_PENDING, &item->flags))
631 return ret; 612 return;
632 } 613 }
633 dreq = req->defer(req); 614 dreq = req->defer(req);
634 if (dreq == NULL) 615 if (dreq == NULL)
635 return -ENOMEM; 616 return;
636 return setup_deferral(dreq, item); 617 setup_deferral(dreq, item);
618 if (!test_bit(CACHE_PENDING, &item->flags))
619 /* Bit could have been cleared before we managed to
620 * set up the deferral, so need to revisit just in case
621 */
622 cache_revisit_request(item);
637} 623}
638 624
639static void cache_revisit_request(struct cache_head *item) 625static void cache_revisit_request(struct cache_head *item)