diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-04-01 13:28:15 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-04-01 13:28:15 -0400 |
commit | cc85906110e26fe8537c3bdbc08a74ae8110030b (patch) | |
tree | 891813098ede3dba4d5ff3b83b1f7b491367ad2f /net/sunrpc/svc.c | |
parent | c09bca786ff941ed17c5f381c4eca5b106808c51 (diff) | |
parent | c69da774b28e01e062e0a3aba7509f2dcfd2a11a (diff) |
Merge branch 'devel' into for-linus
Diffstat (limited to 'net/sunrpc/svc.c')
-rw-r--r-- | net/sunrpc/svc.c | 158 |
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 | */ |
360 | static struct svc_serv * | 360 | static 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 | ||
428 | struct svc_serv * | 427 | struct svc_serv * |
429 | svc_create(struct svc_program *prog, unsigned int bufsize, | 428 | svc_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 | } |
434 | EXPORT_SYMBOL_GPL(svc_create); | 433 | EXPORT_SYMBOL_GPL(svc_create); |
435 | 434 | ||
436 | struct svc_serv * | 435 | struct svc_serv * |
437 | svc_create_pooled(struct svc_program *prog, unsigned int bufsize, | 436 | svc_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 | } |
720 | EXPORT_SYMBOL_GPL(svc_exit_thread); | 719 | EXPORT_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 | */ |
802 | static int __svc_register(const u32 program, const u32 version, | 821 | static 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 | */ | ||
842 | static 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 | */ |
863 | int svc_register(const struct svc_serv *serv, const unsigned short proto, | 856 | int 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 | */ | ||
901 | static void __svc_unregister(const u32 program, const u32 version, | 899 | static 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 | ||
919 | static 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 |