aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2009-04-01 13:28:15 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-04-01 13:28:15 -0400
commitcc85906110e26fe8537c3bdbc08a74ae8110030b (patch)
tree891813098ede3dba4d5ff3b83b1f7b491367ad2f /net/sunrpc/svc.c
parentc09bca786ff941ed17c5f381c4eca5b106808c51 (diff)
parentc69da774b28e01e062e0a3aba7509f2dcfd2a11a (diff)
Merge branch 'devel' into for-linus
Diffstat (limited to 'net/sunrpc/svc.c')
-rw-r--r--net/sunrpc/svc.c158
1 files changed, 72 insertions, 86 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index bb507e2bb94d..9f2f2412a2f3 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -359,7 +359,7 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu)
359 */ 359 */
360static struct svc_serv * 360static struct svc_serv *
361__svc_create(struct svc_program *prog, unsigned int bufsize, int npools, 361__svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
362 sa_family_t family, void (*shutdown)(struct svc_serv *serv)) 362 void (*shutdown)(struct svc_serv *serv))
363{ 363{
364 struct svc_serv *serv; 364 struct svc_serv *serv;
365 unsigned int vers; 365 unsigned int vers;
@@ -368,7 +368,6 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
368 368
369 if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL))) 369 if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL)))
370 return NULL; 370 return NULL;
371 serv->sv_family = family;
372 serv->sv_name = prog->pg_name; 371 serv->sv_name = prog->pg_name;
373 serv->sv_program = prog; 372 serv->sv_program = prog;
374 serv->sv_nrthreads = 1; 373 serv->sv_nrthreads = 1;
@@ -427,21 +426,21 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
427 426
428struct svc_serv * 427struct svc_serv *
429svc_create(struct svc_program *prog, unsigned int bufsize, 428svc_create(struct svc_program *prog, unsigned int bufsize,
430 sa_family_t family, void (*shutdown)(struct svc_serv *serv)) 429 void (*shutdown)(struct svc_serv *serv))
431{ 430{
432 return __svc_create(prog, bufsize, /*npools*/1, family, shutdown); 431 return __svc_create(prog, bufsize, /*npools*/1, shutdown);
433} 432}
434EXPORT_SYMBOL_GPL(svc_create); 433EXPORT_SYMBOL_GPL(svc_create);
435 434
436struct svc_serv * 435struct svc_serv *
437svc_create_pooled(struct svc_program *prog, unsigned int bufsize, 436svc_create_pooled(struct svc_program *prog, unsigned int bufsize,
438 sa_family_t family, void (*shutdown)(struct svc_serv *serv), 437 void (*shutdown)(struct svc_serv *serv),
439 svc_thread_fn func, struct module *mod) 438 svc_thread_fn func, struct module *mod)
440{ 439{
441 struct svc_serv *serv; 440 struct svc_serv *serv;
442 unsigned int npools = svc_pool_map_get(); 441 unsigned int npools = svc_pool_map_get();
443 442
444 serv = __svc_create(prog, bufsize, npools, family, shutdown); 443 serv = __svc_create(prog, bufsize, npools, shutdown);
445 444
446 if (serv != NULL) { 445 if (serv != NULL) {
447 serv->sv_function = func; 446 serv->sv_function = func;
@@ -719,8 +718,6 @@ svc_exit_thread(struct svc_rqst *rqstp)
719} 718}
720EXPORT_SYMBOL_GPL(svc_exit_thread); 719EXPORT_SYMBOL_GPL(svc_exit_thread);
721 720
722#ifdef CONFIG_SUNRPC_REGISTER_V4
723
724/* 721/*
725 * Register an "inet" protocol family netid with the local 722 * Register an "inet" protocol family netid with the local
726 * rpcbind daemon via an rpcbind v4 SET request. 723 * rpcbind daemon via an rpcbind v4 SET request.
@@ -735,12 +732,13 @@ static int __svc_rpcb_register4(const u32 program, const u32 version,
735 const unsigned short protocol, 732 const unsigned short protocol,
736 const unsigned short port) 733 const unsigned short port)
737{ 734{
738 struct sockaddr_in sin = { 735 const struct sockaddr_in sin = {
739 .sin_family = AF_INET, 736 .sin_family = AF_INET,
740 .sin_addr.s_addr = htonl(INADDR_ANY), 737 .sin_addr.s_addr = htonl(INADDR_ANY),
741 .sin_port = htons(port), 738 .sin_port = htons(port),
742 }; 739 };
743 char *netid; 740 const char *netid;
741 int error;
744 742
745 switch (protocol) { 743 switch (protocol) {
746 case IPPROTO_UDP: 744 case IPPROTO_UDP:
@@ -750,13 +748,23 @@ static int __svc_rpcb_register4(const u32 program, const u32 version,
750 netid = RPCBIND_NETID_TCP; 748 netid = RPCBIND_NETID_TCP;
751 break; 749 break;
752 default: 750 default:
753 return -EPROTONOSUPPORT; 751 return -ENOPROTOOPT;
754 } 752 }
755 753
756 return rpcb_v4_register(program, version, 754 error = rpcb_v4_register(program, version,
757 (struct sockaddr *)&sin, netid); 755 (const struct sockaddr *)&sin, netid);
756
757 /*
758 * User space didn't support rpcbind v4, so retry this
759 * registration request with the legacy rpcbind v2 protocol.
760 */
761 if (error == -EPROTONOSUPPORT)
762 error = rpcb_register(program, version, protocol, port);
763
764 return error;
758} 765}
759 766
767#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
760/* 768/*
761 * Register an "inet6" protocol family netid with the local 769 * Register an "inet6" protocol family netid with the local
762 * rpcbind daemon via an rpcbind v4 SET request. 770 * rpcbind daemon via an rpcbind v4 SET request.
@@ -771,12 +779,13 @@ static int __svc_rpcb_register6(const u32 program, const u32 version,
771 const unsigned short protocol, 779 const unsigned short protocol,
772 const unsigned short port) 780 const unsigned short port)
773{ 781{
774 struct sockaddr_in6 sin6 = { 782 const struct sockaddr_in6 sin6 = {
775 .sin6_family = AF_INET6, 783 .sin6_family = AF_INET6,
776 .sin6_addr = IN6ADDR_ANY_INIT, 784 .sin6_addr = IN6ADDR_ANY_INIT,
777 .sin6_port = htons(port), 785 .sin6_port = htons(port),
778 }; 786 };
779 char *netid; 787 const char *netid;
788 int error;
780 789
781 switch (protocol) { 790 switch (protocol) {
782 case IPPROTO_UDP: 791 case IPPROTO_UDP:
@@ -786,12 +795,22 @@ static int __svc_rpcb_register6(const u32 program, const u32 version,
786 netid = RPCBIND_NETID_TCP6; 795 netid = RPCBIND_NETID_TCP6;
787 break; 796 break;
788 default: 797 default:
789 return -EPROTONOSUPPORT; 798 return -ENOPROTOOPT;
790 } 799 }
791 800
792 return rpcb_v4_register(program, version, 801 error = rpcb_v4_register(program, version,
793 (struct sockaddr *)&sin6, netid); 802 (const struct sockaddr *)&sin6, netid);
803
804 /*
805 * User space didn't support rpcbind version 4, so we won't
806 * use a PF_INET6 listener.
807 */
808 if (error == -EPROTONOSUPPORT)
809 error = -EAFNOSUPPORT;
810
811 return error;
794} 812}
813#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
795 814
796/* 815/*
797 * Register a kernel RPC service via rpcbind version 4. 816 * Register a kernel RPC service via rpcbind version 4.
@@ -799,69 +818,43 @@ static int __svc_rpcb_register6(const u32 program, const u32 version,
799 * Returns zero on success; a negative errno value is returned 818 * Returns zero on success; a negative errno value is returned
800 * if any error occurs. 819 * if any error occurs.
801 */ 820 */
802static int __svc_register(const u32 program, const u32 version, 821static int __svc_register(const char *progname,
803 const sa_family_t family, 822 const u32 program, const u32 version,
823 const int family,
804 const unsigned short protocol, 824 const unsigned short protocol,
805 const unsigned short port) 825 const unsigned short port)
806{ 826{
807 int error; 827 int error = -EAFNOSUPPORT;
808 828
809 switch (family) { 829 switch (family) {
810 case AF_INET: 830 case PF_INET:
811 return __svc_rpcb_register4(program, version, 831 error = __svc_rpcb_register4(program, version,
812 protocol, port); 832 protocol, port);
813 case AF_INET6: 833 break;
834#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
835 case PF_INET6:
814 error = __svc_rpcb_register6(program, version, 836 error = __svc_rpcb_register6(program, version,
815 protocol, port); 837 protocol, port);
816 if (error < 0) 838#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
817 return error;
818
819 /*
820 * Work around bug in some versions of Linux rpcbind
821 * which don't allow registration of both inet and
822 * inet6 netids.
823 *
824 * Error return ignored for now.
825 */
826 __svc_rpcb_register4(program, version,
827 protocol, port);
828 return 0;
829 } 839 }
830 840
831 return -EAFNOSUPPORT; 841 if (error < 0)
832} 842 printk(KERN_WARNING "svc: failed to register %sv%u RPC "
833 843 "service (errno %d).\n", progname, version, -error);
834#else /* CONFIG_SUNRPC_REGISTER_V4 */ 844 return error;
835
836/*
837 * Register a kernel RPC service via rpcbind version 2.
838 *
839 * Returns zero on success; a negative errno value is returned
840 * if any error occurs.
841 */
842static int __svc_register(const u32 program, const u32 version,
843 sa_family_t family,
844 const unsigned short protocol,
845 const unsigned short port)
846{
847 if (family != AF_INET)
848 return -EAFNOSUPPORT;
849
850 return rpcb_register(program, version, protocol, port);
851} 845}
852 846
853#endif /* CONFIG_SUNRPC_REGISTER_V4 */
854
855/** 847/**
856 * svc_register - register an RPC service with the local portmapper 848 * svc_register - register an RPC service with the local portmapper
857 * @serv: svc_serv struct for the service to register 849 * @serv: svc_serv struct for the service to register
850 * @family: protocol family of service's listener socket
858 * @proto: transport protocol number to advertise 851 * @proto: transport protocol number to advertise
859 * @port: port to advertise 852 * @port: port to advertise
860 * 853 *
861 * Service is registered for any address in serv's address family 854 * Service is registered for any address in the passed-in protocol family
862 */ 855 */
863int svc_register(const struct svc_serv *serv, const unsigned short proto, 856int svc_register(const struct svc_serv *serv, const int family,
864 const unsigned short port) 857 const unsigned short proto, const unsigned short port)
865{ 858{
866 struct svc_program *progp; 859 struct svc_program *progp;
867 unsigned int i; 860 unsigned int i;
@@ -879,15 +872,15 @@ int svc_register(const struct svc_serv *serv, const unsigned short proto,
879 i, 872 i,
880 proto == IPPROTO_UDP? "udp" : "tcp", 873 proto == IPPROTO_UDP? "udp" : "tcp",
881 port, 874 port,
882 serv->sv_family, 875 family,
883 progp->pg_vers[i]->vs_hidden? 876 progp->pg_vers[i]->vs_hidden?
884 " (but not telling portmap)" : ""); 877 " (but not telling portmap)" : "");
885 878
886 if (progp->pg_vers[i]->vs_hidden) 879 if (progp->pg_vers[i]->vs_hidden)
887 continue; 880 continue;
888 881
889 error = __svc_register(progp->pg_prog, i, 882 error = __svc_register(progp->pg_name, progp->pg_prog,
890 serv->sv_family, proto, port); 883 i, family, proto, port);
891 if (error < 0) 884 if (error < 0)
892 break; 885 break;
893 } 886 }
@@ -896,38 +889,31 @@ int svc_register(const struct svc_serv *serv, const unsigned short proto,
896 return error; 889 return error;
897} 890}
898 891
899#ifdef CONFIG_SUNRPC_REGISTER_V4 892/*
900 893 * If user space is running rpcbind, it should take the v4 UNSET
894 * and clear everything for this [program, version]. If user space
895 * is running portmap, it will reject the v4 UNSET, but won't have
896 * any "inet6" entries anyway. So a PMAP_UNSET should be sufficient
897 * in this case to clear all existing entries for [program, version].
898 */
901static void __svc_unregister(const u32 program, const u32 version, 899static void __svc_unregister(const u32 program, const u32 version,
902 const char *progname) 900 const char *progname)
903{ 901{
904 struct sockaddr_in6 sin6 = {
905 .sin6_family = AF_INET6,
906 .sin6_addr = IN6ADDR_ANY_INIT,
907 .sin6_port = 0,
908 };
909 int error; 902 int error;
910 903
911 error = rpcb_v4_register(program, version, 904 error = rpcb_v4_register(program, version, NULL, "");
912 (struct sockaddr *)&sin6, "");
913 dprintk("svc: %s(%sv%u), error %d\n",
914 __func__, progname, version, error);
915}
916
917#else /* CONFIG_SUNRPC_REGISTER_V4 */
918 905
919static void __svc_unregister(const u32 program, const u32 version, 906 /*
920 const char *progname) 907 * User space didn't support rpcbind v4, so retry this
921{ 908 * request with the legacy rpcbind v2 protocol.
922 int error; 909 */
910 if (error == -EPROTONOSUPPORT)
911 error = rpcb_register(program, version, 0, 0);
923 912
924 error = rpcb_register(program, version, 0, 0);
925 dprintk("svc: %s(%sv%u), error %d\n", 913 dprintk("svc: %s(%sv%u), error %d\n",
926 __func__, progname, version, error); 914 __func__, progname, version, error);
927} 915}
928 916
929#endif /* CONFIG_SUNRPC_REGISTER_V4 */
930
931/* 917/*
932 * All netids, bind addresses and ports registered for [program, version] 918 * All netids, bind addresses and ports registered for [program, version]
933 * are removed from the local rpcbind database (if the service is not 919 * are removed from the local rpcbind database (if the service is not