diff options
Diffstat (limited to 'net/sunrpc/svc.c')
-rw-r--r-- | net/sunrpc/svc.c | 164 |
1 files changed, 75 insertions, 89 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index bb507e2bb94d..8847add6ca16 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -317,8 +317,7 @@ svc_pool_map_set_cpumask(struct task_struct *task, unsigned int pidx) | |||
317 | } | 317 | } |
318 | case SVC_POOL_PERNODE: | 318 | case SVC_POOL_PERNODE: |
319 | { | 319 | { |
320 | node_to_cpumask_ptr(nodecpumask, node); | 320 | set_cpus_allowed_ptr(task, cpumask_of_node(node)); |
321 | set_cpus_allowed_ptr(task, nodecpumask); | ||
322 | break; | 321 | break; |
323 | } | 322 | } |
324 | } | 323 | } |
@@ -359,7 +358,7 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu) | |||
359 | */ | 358 | */ |
360 | static struct svc_serv * | 359 | static struct svc_serv * |
361 | __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, | 360 | __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, |
362 | sa_family_t family, void (*shutdown)(struct svc_serv *serv)) | 361 | void (*shutdown)(struct svc_serv *serv)) |
363 | { | 362 | { |
364 | struct svc_serv *serv; | 363 | struct svc_serv *serv; |
365 | unsigned int vers; | 364 | unsigned int vers; |
@@ -368,7 +367,6 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, | |||
368 | 367 | ||
369 | if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL))) | 368 | if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL))) |
370 | return NULL; | 369 | return NULL; |
371 | serv->sv_family = family; | ||
372 | serv->sv_name = prog->pg_name; | 370 | serv->sv_name = prog->pg_name; |
373 | serv->sv_program = prog; | 371 | serv->sv_program = prog; |
374 | serv->sv_nrthreads = 1; | 372 | serv->sv_nrthreads = 1; |
@@ -427,21 +425,21 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, | |||
427 | 425 | ||
428 | struct svc_serv * | 426 | struct svc_serv * |
429 | svc_create(struct svc_program *prog, unsigned int bufsize, | 427 | svc_create(struct svc_program *prog, unsigned int bufsize, |
430 | sa_family_t family, void (*shutdown)(struct svc_serv *serv)) | 428 | void (*shutdown)(struct svc_serv *serv)) |
431 | { | 429 | { |
432 | return __svc_create(prog, bufsize, /*npools*/1, family, shutdown); | 430 | return __svc_create(prog, bufsize, /*npools*/1, shutdown); |
433 | } | 431 | } |
434 | EXPORT_SYMBOL_GPL(svc_create); | 432 | EXPORT_SYMBOL_GPL(svc_create); |
435 | 433 | ||
436 | struct svc_serv * | 434 | struct svc_serv * |
437 | svc_create_pooled(struct svc_program *prog, unsigned int bufsize, | 435 | svc_create_pooled(struct svc_program *prog, unsigned int bufsize, |
438 | sa_family_t family, void (*shutdown)(struct svc_serv *serv), | 436 | void (*shutdown)(struct svc_serv *serv), |
439 | svc_thread_fn func, struct module *mod) | 437 | svc_thread_fn func, struct module *mod) |
440 | { | 438 | { |
441 | struct svc_serv *serv; | 439 | struct svc_serv *serv; |
442 | unsigned int npools = svc_pool_map_get(); | 440 | unsigned int npools = svc_pool_map_get(); |
443 | 441 | ||
444 | serv = __svc_create(prog, bufsize, npools, family, shutdown); | 442 | serv = __svc_create(prog, bufsize, npools, shutdown); |
445 | 443 | ||
446 | if (serv != NULL) { | 444 | if (serv != NULL) { |
447 | serv->sv_function = func; | 445 | serv->sv_function = func; |
@@ -719,8 +717,6 @@ svc_exit_thread(struct svc_rqst *rqstp) | |||
719 | } | 717 | } |
720 | EXPORT_SYMBOL_GPL(svc_exit_thread); | 718 | EXPORT_SYMBOL_GPL(svc_exit_thread); |
721 | 719 | ||
722 | #ifdef CONFIG_SUNRPC_REGISTER_V4 | ||
723 | |||
724 | /* | 720 | /* |
725 | * Register an "inet" protocol family netid with the local | 721 | * Register an "inet" protocol family netid with the local |
726 | * rpcbind daemon via an rpcbind v4 SET request. | 722 | * rpcbind daemon via an rpcbind v4 SET request. |
@@ -735,12 +731,13 @@ static int __svc_rpcb_register4(const u32 program, const u32 version, | |||
735 | const unsigned short protocol, | 731 | const unsigned short protocol, |
736 | const unsigned short port) | 732 | const unsigned short port) |
737 | { | 733 | { |
738 | struct sockaddr_in sin = { | 734 | const struct sockaddr_in sin = { |
739 | .sin_family = AF_INET, | 735 | .sin_family = AF_INET, |
740 | .sin_addr.s_addr = htonl(INADDR_ANY), | 736 | .sin_addr.s_addr = htonl(INADDR_ANY), |
741 | .sin_port = htons(port), | 737 | .sin_port = htons(port), |
742 | }; | 738 | }; |
743 | char *netid; | 739 | const char *netid; |
740 | int error; | ||
744 | 741 | ||
745 | switch (protocol) { | 742 | switch (protocol) { |
746 | case IPPROTO_UDP: | 743 | case IPPROTO_UDP: |
@@ -750,13 +747,23 @@ static int __svc_rpcb_register4(const u32 program, const u32 version, | |||
750 | netid = RPCBIND_NETID_TCP; | 747 | netid = RPCBIND_NETID_TCP; |
751 | break; | 748 | break; |
752 | default: | 749 | default: |
753 | return -EPROTONOSUPPORT; | 750 | return -ENOPROTOOPT; |
754 | } | 751 | } |
755 | 752 | ||
756 | return rpcb_v4_register(program, version, | 753 | error = rpcb_v4_register(program, version, |
757 | (struct sockaddr *)&sin, netid); | 754 | (const struct sockaddr *)&sin, netid); |
755 | |||
756 | /* | ||
757 | * User space didn't support rpcbind v4, so retry this | ||
758 | * registration request with the legacy rpcbind v2 protocol. | ||
759 | */ | ||
760 | if (error == -EPROTONOSUPPORT) | ||
761 | error = rpcb_register(program, version, protocol, port); | ||
762 | |||
763 | return error; | ||
758 | } | 764 | } |
759 | 765 | ||
766 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
760 | /* | 767 | /* |
761 | * Register an "inet6" protocol family netid with the local | 768 | * Register an "inet6" protocol family netid with the local |
762 | * rpcbind daemon via an rpcbind v4 SET request. | 769 | * rpcbind daemon via an rpcbind v4 SET request. |
@@ -771,12 +778,13 @@ static int __svc_rpcb_register6(const u32 program, const u32 version, | |||
771 | const unsigned short protocol, | 778 | const unsigned short protocol, |
772 | const unsigned short port) | 779 | const unsigned short port) |
773 | { | 780 | { |
774 | struct sockaddr_in6 sin6 = { | 781 | const struct sockaddr_in6 sin6 = { |
775 | .sin6_family = AF_INET6, | 782 | .sin6_family = AF_INET6, |
776 | .sin6_addr = IN6ADDR_ANY_INIT, | 783 | .sin6_addr = IN6ADDR_ANY_INIT, |
777 | .sin6_port = htons(port), | 784 | .sin6_port = htons(port), |
778 | }; | 785 | }; |
779 | char *netid; | 786 | const char *netid; |
787 | int error; | ||
780 | 788 | ||
781 | switch (protocol) { | 789 | switch (protocol) { |
782 | case IPPROTO_UDP: | 790 | case IPPROTO_UDP: |
@@ -786,12 +794,22 @@ static int __svc_rpcb_register6(const u32 program, const u32 version, | |||
786 | netid = RPCBIND_NETID_TCP6; | 794 | netid = RPCBIND_NETID_TCP6; |
787 | break; | 795 | break; |
788 | default: | 796 | default: |
789 | return -EPROTONOSUPPORT; | 797 | return -ENOPROTOOPT; |
790 | } | 798 | } |
791 | 799 | ||
792 | return rpcb_v4_register(program, version, | 800 | error = rpcb_v4_register(program, version, |
793 | (struct sockaddr *)&sin6, netid); | 801 | (const struct sockaddr *)&sin6, netid); |
802 | |||
803 | /* | ||
804 | * User space didn't support rpcbind version 4, so we won't | ||
805 | * use a PF_INET6 listener. | ||
806 | */ | ||
807 | if (error == -EPROTONOSUPPORT) | ||
808 | error = -EAFNOSUPPORT; | ||
809 | |||
810 | return error; | ||
794 | } | 811 | } |
812 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | ||
795 | 813 | ||
796 | /* | 814 | /* |
797 | * Register a kernel RPC service via rpcbind version 4. | 815 | * Register a kernel RPC service via rpcbind version 4. |
@@ -799,69 +817,43 @@ static int __svc_rpcb_register6(const u32 program, const u32 version, | |||
799 | * Returns zero on success; a negative errno value is returned | 817 | * Returns zero on success; a negative errno value is returned |
800 | * if any error occurs. | 818 | * if any error occurs. |
801 | */ | 819 | */ |
802 | static int __svc_register(const u32 program, const u32 version, | 820 | static int __svc_register(const char *progname, |
803 | const sa_family_t family, | 821 | const u32 program, const u32 version, |
822 | const int family, | ||
804 | const unsigned short protocol, | 823 | const unsigned short protocol, |
805 | const unsigned short port) | 824 | const unsigned short port) |
806 | { | 825 | { |
807 | int error; | 826 | int error = -EAFNOSUPPORT; |
808 | 827 | ||
809 | switch (family) { | 828 | switch (family) { |
810 | case AF_INET: | 829 | case PF_INET: |
811 | return __svc_rpcb_register4(program, version, | 830 | error = __svc_rpcb_register4(program, version, |
812 | protocol, port); | 831 | protocol, port); |
813 | case AF_INET6: | 832 | break; |
833 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
834 | case PF_INET6: | ||
814 | error = __svc_rpcb_register6(program, version, | 835 | error = __svc_rpcb_register6(program, version, |
815 | protocol, port); | 836 | protocol, port); |
816 | if (error < 0) | 837 | #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 | } | 838 | } |
830 | 839 | ||
831 | return -EAFNOSUPPORT; | 840 | if (error < 0) |
832 | } | 841 | printk(KERN_WARNING "svc: failed to register %sv%u RPC " |
833 | 842 | "service (errno %d).\n", progname, version, -error); | |
834 | #else /* CONFIG_SUNRPC_REGISTER_V4 */ | 843 | 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 | } | 844 | } |
852 | 845 | ||
853 | #endif /* CONFIG_SUNRPC_REGISTER_V4 */ | ||
854 | |||
855 | /** | 846 | /** |
856 | * svc_register - register an RPC service with the local portmapper | 847 | * svc_register - register an RPC service with the local portmapper |
857 | * @serv: svc_serv struct for the service to register | 848 | * @serv: svc_serv struct for the service to register |
849 | * @family: protocol family of service's listener socket | ||
858 | * @proto: transport protocol number to advertise | 850 | * @proto: transport protocol number to advertise |
859 | * @port: port to advertise | 851 | * @port: port to advertise |
860 | * | 852 | * |
861 | * Service is registered for any address in serv's address family | 853 | * Service is registered for any address in the passed-in protocol family |
862 | */ | 854 | */ |
863 | int svc_register(const struct svc_serv *serv, const unsigned short proto, | 855 | int svc_register(const struct svc_serv *serv, const int family, |
864 | const unsigned short port) | 856 | const unsigned short proto, const unsigned short port) |
865 | { | 857 | { |
866 | struct svc_program *progp; | 858 | struct svc_program *progp; |
867 | unsigned int i; | 859 | unsigned int i; |
@@ -879,15 +871,15 @@ int svc_register(const struct svc_serv *serv, const unsigned short proto, | |||
879 | i, | 871 | i, |
880 | proto == IPPROTO_UDP? "udp" : "tcp", | 872 | proto == IPPROTO_UDP? "udp" : "tcp", |
881 | port, | 873 | port, |
882 | serv->sv_family, | 874 | family, |
883 | progp->pg_vers[i]->vs_hidden? | 875 | progp->pg_vers[i]->vs_hidden? |
884 | " (but not telling portmap)" : ""); | 876 | " (but not telling portmap)" : ""); |
885 | 877 | ||
886 | if (progp->pg_vers[i]->vs_hidden) | 878 | if (progp->pg_vers[i]->vs_hidden) |
887 | continue; | 879 | continue; |
888 | 880 | ||
889 | error = __svc_register(progp->pg_prog, i, | 881 | error = __svc_register(progp->pg_name, progp->pg_prog, |
890 | serv->sv_family, proto, port); | 882 | i, family, proto, port); |
891 | if (error < 0) | 883 | if (error < 0) |
892 | break; | 884 | break; |
893 | } | 885 | } |
@@ -896,38 +888,31 @@ int svc_register(const struct svc_serv *serv, const unsigned short proto, | |||
896 | return error; | 888 | return error; |
897 | } | 889 | } |
898 | 890 | ||
899 | #ifdef CONFIG_SUNRPC_REGISTER_V4 | 891 | /* |
900 | 892 | * If user space is running rpcbind, it should take the v4 UNSET | |
893 | * and clear everything for this [program, version]. If user space | ||
894 | * is running portmap, it will reject the v4 UNSET, but won't have | ||
895 | * any "inet6" entries anyway. So a PMAP_UNSET should be sufficient | ||
896 | * in this case to clear all existing entries for [program, version]. | ||
897 | */ | ||
901 | static void __svc_unregister(const u32 program, const u32 version, | 898 | static void __svc_unregister(const u32 program, const u32 version, |
902 | const char *progname) | 899 | const char *progname) |
903 | { | 900 | { |
904 | struct sockaddr_in6 sin6 = { | ||
905 | .sin6_family = AF_INET6, | ||
906 | .sin6_addr = IN6ADDR_ANY_INIT, | ||
907 | .sin6_port = 0, | ||
908 | }; | ||
909 | int error; | 901 | int error; |
910 | 902 | ||
911 | error = rpcb_v4_register(program, version, | 903 | 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 | 904 | ||
919 | static void __svc_unregister(const u32 program, const u32 version, | 905 | /* |
920 | const char *progname) | 906 | * User space didn't support rpcbind v4, so retry this |
921 | { | 907 | * request with the legacy rpcbind v2 protocol. |
922 | int error; | 908 | */ |
909 | if (error == -EPROTONOSUPPORT) | ||
910 | error = rpcb_register(program, version, 0, 0); | ||
923 | 911 | ||
924 | error = rpcb_register(program, version, 0, 0); | ||
925 | dprintk("svc: %s(%sv%u), error %d\n", | 912 | dprintk("svc: %s(%sv%u), error %d\n", |
926 | __func__, progname, version, error); | 913 | __func__, progname, version, error); |
927 | } | 914 | } |
928 | 915 | ||
929 | #endif /* CONFIG_SUNRPC_REGISTER_V4 */ | ||
930 | |||
931 | /* | 916 | /* |
932 | * All netids, bind addresses and ports registered for [program, version] | 917 | * All netids, bind addresses and ports registered for [program, version] |
933 | * are removed from the local rpcbind database (if the service is not | 918 | * are removed from the local rpcbind database (if the service is not |
@@ -1023,6 +1008,8 @@ svc_process(struct svc_rqst *rqstp) | |||
1023 | rqstp->rq_res.tail[0].iov_len = 0; | 1008 | rqstp->rq_res.tail[0].iov_len = 0; |
1024 | /* Will be turned off only in gss privacy case: */ | 1009 | /* Will be turned off only in gss privacy case: */ |
1025 | rqstp->rq_splice_ok = 1; | 1010 | rqstp->rq_splice_ok = 1; |
1011 | /* Will be turned off only when NFSv4 Sessions are used */ | ||
1012 | rqstp->rq_usedeferral = 1; | ||
1026 | 1013 | ||
1027 | /* Setup reply header */ | 1014 | /* Setup reply header */ |
1028 | rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); | 1015 | rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); |
@@ -1093,7 +1080,6 @@ svc_process(struct svc_rqst *rqstp) | |||
1093 | procp = versp->vs_proc + proc; | 1080 | procp = versp->vs_proc + proc; |
1094 | if (proc >= versp->vs_nproc || !procp->pc_func) | 1081 | if (proc >= versp->vs_nproc || !procp->pc_func) |
1095 | goto err_bad_proc; | 1082 | goto err_bad_proc; |
1096 | rqstp->rq_server = serv; | ||
1097 | rqstp->rq_procinfo = procp; | 1083 | rqstp->rq_procinfo = procp; |
1098 | 1084 | ||
1099 | /* Syntactic check complete */ | 1085 | /* Syntactic check complete */ |