diff options
Diffstat (limited to 'net/sunrpc/svc.c')
-rw-r--r-- | net/sunrpc/svc.c | 90 |
1 files changed, 58 insertions, 32 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 4ad5fbbb18b4..a290e1523297 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -364,7 +364,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, | |||
364 | void (*shutdown)(struct svc_serv *serv)) | 364 | void (*shutdown)(struct svc_serv *serv)) |
365 | { | 365 | { |
366 | struct svc_serv *serv; | 366 | struct svc_serv *serv; |
367 | int vers; | 367 | unsigned int vers; |
368 | unsigned int xdrsize; | 368 | unsigned int xdrsize; |
369 | unsigned int i; | 369 | unsigned int i; |
370 | 370 | ||
@@ -433,6 +433,7 @@ svc_create(struct svc_program *prog, unsigned int bufsize, | |||
433 | { | 433 | { |
434 | return __svc_create(prog, bufsize, /*npools*/1, shutdown); | 434 | return __svc_create(prog, bufsize, /*npools*/1, shutdown); |
435 | } | 435 | } |
436 | EXPORT_SYMBOL(svc_create); | ||
436 | 437 | ||
437 | struct svc_serv * | 438 | struct svc_serv * |
438 | svc_create_pooled(struct svc_program *prog, unsigned int bufsize, | 439 | svc_create_pooled(struct svc_program *prog, unsigned int bufsize, |
@@ -452,6 +453,7 @@ svc_create_pooled(struct svc_program *prog, unsigned int bufsize, | |||
452 | 453 | ||
453 | return serv; | 454 | return serv; |
454 | } | 455 | } |
456 | EXPORT_SYMBOL(svc_create_pooled); | ||
455 | 457 | ||
456 | /* | 458 | /* |
457 | * Destroy an RPC service. Should be called with the BKL held | 459 | * Destroy an RPC service. Should be called with the BKL held |
@@ -459,9 +461,6 @@ svc_create_pooled(struct svc_program *prog, unsigned int bufsize, | |||
459 | void | 461 | void |
460 | svc_destroy(struct svc_serv *serv) | 462 | svc_destroy(struct svc_serv *serv) |
461 | { | 463 | { |
462 | struct svc_sock *svsk; | ||
463 | struct svc_sock *tmp; | ||
464 | |||
465 | dprintk("svc: svc_destroy(%s, %d)\n", | 464 | dprintk("svc: svc_destroy(%s, %d)\n", |
466 | serv->sv_program->pg_name, | 465 | serv->sv_program->pg_name, |
467 | serv->sv_nrthreads); | 466 | serv->sv_nrthreads); |
@@ -476,14 +475,12 @@ svc_destroy(struct svc_serv *serv) | |||
476 | 475 | ||
477 | del_timer_sync(&serv->sv_temptimer); | 476 | del_timer_sync(&serv->sv_temptimer); |
478 | 477 | ||
479 | list_for_each_entry_safe(svsk, tmp, &serv->sv_tempsocks, sk_list) | 478 | svc_close_all(&serv->sv_tempsocks); |
480 | svc_force_close_socket(svsk); | ||
481 | 479 | ||
482 | if (serv->sv_shutdown) | 480 | if (serv->sv_shutdown) |
483 | serv->sv_shutdown(serv); | 481 | serv->sv_shutdown(serv); |
484 | 482 | ||
485 | list_for_each_entry_safe(svsk, tmp, &serv->sv_permsocks, sk_list) | 483 | svc_close_all(&serv->sv_permsocks); |
486 | svc_force_close_socket(svsk); | ||
487 | 484 | ||
488 | BUG_ON(!list_empty(&serv->sv_permsocks)); | 485 | BUG_ON(!list_empty(&serv->sv_permsocks)); |
489 | BUG_ON(!list_empty(&serv->sv_tempsocks)); | 486 | BUG_ON(!list_empty(&serv->sv_tempsocks)); |
@@ -498,6 +495,7 @@ svc_destroy(struct svc_serv *serv) | |||
498 | kfree(serv->sv_pools); | 495 | kfree(serv->sv_pools); |
499 | kfree(serv); | 496 | kfree(serv); |
500 | } | 497 | } |
498 | EXPORT_SYMBOL(svc_destroy); | ||
501 | 499 | ||
502 | /* | 500 | /* |
503 | * Allocate an RPC server's buffer space. | 501 | * Allocate an RPC server's buffer space. |
@@ -536,31 +534,17 @@ svc_release_buffer(struct svc_rqst *rqstp) | |||
536 | put_page(rqstp->rq_pages[i]); | 534 | put_page(rqstp->rq_pages[i]); |
537 | } | 535 | } |
538 | 536 | ||
539 | /* | 537 | struct svc_rqst * |
540 | * Create a thread in the given pool. Caller must hold BKL. | 538 | svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool) |
541 | * On a NUMA or SMP machine, with a multi-pool serv, the thread | ||
542 | * will be restricted to run on the cpus belonging to the pool. | ||
543 | */ | ||
544 | static int | ||
545 | __svc_create_thread(svc_thread_fn func, struct svc_serv *serv, | ||
546 | struct svc_pool *pool) | ||
547 | { | 539 | { |
548 | struct svc_rqst *rqstp; | 540 | struct svc_rqst *rqstp; |
549 | int error = -ENOMEM; | ||
550 | int have_oldmask = 0; | ||
551 | cpumask_t oldmask; | ||
552 | 541 | ||
553 | rqstp = kzalloc(sizeof(*rqstp), GFP_KERNEL); | 542 | rqstp = kzalloc(sizeof(*rqstp), GFP_KERNEL); |
554 | if (!rqstp) | 543 | if (!rqstp) |
555 | goto out; | 544 | goto out_enomem; |
556 | 545 | ||
557 | init_waitqueue_head(&rqstp->rq_wait); | 546 | init_waitqueue_head(&rqstp->rq_wait); |
558 | 547 | ||
559 | if (!(rqstp->rq_argp = kmalloc(serv->sv_xdrsize, GFP_KERNEL)) | ||
560 | || !(rqstp->rq_resp = kmalloc(serv->sv_xdrsize, GFP_KERNEL)) | ||
561 | || !svc_init_buffer(rqstp, serv->sv_max_mesg)) | ||
562 | goto out_thread; | ||
563 | |||
564 | serv->sv_nrthreads++; | 548 | serv->sv_nrthreads++; |
565 | spin_lock_bh(&pool->sp_lock); | 549 | spin_lock_bh(&pool->sp_lock); |
566 | pool->sp_nrthreads++; | 550 | pool->sp_nrthreads++; |
@@ -569,6 +553,45 @@ __svc_create_thread(svc_thread_fn func, struct svc_serv *serv, | |||
569 | rqstp->rq_server = serv; | 553 | rqstp->rq_server = serv; |
570 | rqstp->rq_pool = pool; | 554 | rqstp->rq_pool = pool; |
571 | 555 | ||
556 | rqstp->rq_argp = kmalloc(serv->sv_xdrsize, GFP_KERNEL); | ||
557 | if (!rqstp->rq_argp) | ||
558 | goto out_thread; | ||
559 | |||
560 | rqstp->rq_resp = kmalloc(serv->sv_xdrsize, GFP_KERNEL); | ||
561 | if (!rqstp->rq_resp) | ||
562 | goto out_thread; | ||
563 | |||
564 | if (!svc_init_buffer(rqstp, serv->sv_max_mesg)) | ||
565 | goto out_thread; | ||
566 | |||
567 | return rqstp; | ||
568 | out_thread: | ||
569 | svc_exit_thread(rqstp); | ||
570 | out_enomem: | ||
571 | return ERR_PTR(-ENOMEM); | ||
572 | } | ||
573 | EXPORT_SYMBOL(svc_prepare_thread); | ||
574 | |||
575 | /* | ||
576 | * Create a thread in the given pool. Caller must hold BKL. | ||
577 | * On a NUMA or SMP machine, with a multi-pool serv, the thread | ||
578 | * will be restricted to run on the cpus belonging to the pool. | ||
579 | */ | ||
580 | static int | ||
581 | __svc_create_thread(svc_thread_fn func, struct svc_serv *serv, | ||
582 | struct svc_pool *pool) | ||
583 | { | ||
584 | struct svc_rqst *rqstp; | ||
585 | int error = -ENOMEM; | ||
586 | int have_oldmask = 0; | ||
587 | cpumask_t oldmask; | ||
588 | |||
589 | rqstp = svc_prepare_thread(serv, pool); | ||
590 | if (IS_ERR(rqstp)) { | ||
591 | error = PTR_ERR(rqstp); | ||
592 | goto out; | ||
593 | } | ||
594 | |||
572 | if (serv->sv_nrpools > 1) | 595 | if (serv->sv_nrpools > 1) |
573 | have_oldmask = svc_pool_map_set_cpumask(pool->sp_id, &oldmask); | 596 | have_oldmask = svc_pool_map_set_cpumask(pool->sp_id, &oldmask); |
574 | 597 | ||
@@ -597,6 +620,7 @@ svc_create_thread(svc_thread_fn func, struct svc_serv *serv) | |||
597 | { | 620 | { |
598 | return __svc_create_thread(func, serv, &serv->sv_pools[0]); | 621 | return __svc_create_thread(func, serv, &serv->sv_pools[0]); |
599 | } | 622 | } |
623 | EXPORT_SYMBOL(svc_create_thread); | ||
600 | 624 | ||
601 | /* | 625 | /* |
602 | * Choose a pool in which to create a new thread, for svc_set_num_threads | 626 | * Choose a pool in which to create a new thread, for svc_set_num_threads |
@@ -700,6 +724,7 @@ svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) | |||
700 | 724 | ||
701 | return error; | 725 | return error; |
702 | } | 726 | } |
727 | EXPORT_SYMBOL(svc_set_num_threads); | ||
703 | 728 | ||
704 | /* | 729 | /* |
705 | * Called from a server thread as it's exiting. Caller must hold BKL. | 730 | * Called from a server thread as it's exiting. Caller must hold BKL. |
@@ -726,6 +751,7 @@ svc_exit_thread(struct svc_rqst *rqstp) | |||
726 | if (serv) | 751 | if (serv) |
727 | svc_destroy(serv); | 752 | svc_destroy(serv); |
728 | } | 753 | } |
754 | EXPORT_SYMBOL(svc_exit_thread); | ||
729 | 755 | ||
730 | /* | 756 | /* |
731 | * Register an RPC service with the local portmapper. | 757 | * Register an RPC service with the local portmapper. |
@@ -737,7 +763,8 @@ svc_register(struct svc_serv *serv, int proto, unsigned short port) | |||
737 | { | 763 | { |
738 | struct svc_program *progp; | 764 | struct svc_program *progp; |
739 | unsigned long flags; | 765 | unsigned long flags; |
740 | int i, error = 0, dummy; | 766 | unsigned int i; |
767 | int error = 0, dummy; | ||
741 | 768 | ||
742 | if (!port) | 769 | if (!port) |
743 | clear_thread_flag(TIF_SIGPENDING); | 770 | clear_thread_flag(TIF_SIGPENDING); |
@@ -840,9 +867,9 @@ svc_process(struct svc_rqst *rqstp) | |||
840 | rqstp->rq_res.tail[0].iov_len = 0; | 867 | rqstp->rq_res.tail[0].iov_len = 0; |
841 | /* Will be turned off only in gss privacy case: */ | 868 | /* Will be turned off only in gss privacy case: */ |
842 | rqstp->rq_splice_ok = 1; | 869 | rqstp->rq_splice_ok = 1; |
843 | /* tcp needs a space for the record length... */ | 870 | |
844 | if (rqstp->rq_prot == IPPROTO_TCP) | 871 | /* Setup reply header */ |
845 | svc_putnl(resv, 0); | 872 | rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); |
846 | 873 | ||
847 | rqstp->rq_xid = svc_getu32(argv); | 874 | rqstp->rq_xid = svc_getu32(argv); |
848 | svc_putu32(resv, rqstp->rq_xid); | 875 | svc_putu32(resv, rqstp->rq_xid); |
@@ -1049,16 +1076,15 @@ err_bad: | |||
1049 | svc_putnl(resv, ntohl(rpc_stat)); | 1076 | svc_putnl(resv, ntohl(rpc_stat)); |
1050 | goto sendit; | 1077 | goto sendit; |
1051 | } | 1078 | } |
1079 | EXPORT_SYMBOL(svc_process); | ||
1052 | 1080 | ||
1053 | /* | 1081 | /* |
1054 | * Return (transport-specific) limit on the rpc payload. | 1082 | * Return (transport-specific) limit on the rpc payload. |
1055 | */ | 1083 | */ |
1056 | u32 svc_max_payload(const struct svc_rqst *rqstp) | 1084 | u32 svc_max_payload(const struct svc_rqst *rqstp) |
1057 | { | 1085 | { |
1058 | int max = RPCSVC_MAXPAYLOAD_TCP; | 1086 | u32 max = rqstp->rq_xprt->xpt_class->xcl_max_payload; |
1059 | 1087 | ||
1060 | if (rqstp->rq_sock->sk_sock->type == SOCK_DGRAM) | ||
1061 | max = RPCSVC_MAXPAYLOAD_UDP; | ||
1062 | if (rqstp->rq_server->sv_max_payload < max) | 1088 | if (rqstp->rq_server->sv_max_payload < max) |
1063 | max = rqstp->rq_server->sv_max_payload; | 1089 | max = rqstp->rq_server->sv_max_payload; |
1064 | return max; | 1090 | return max; |