diff options
-rw-r--r-- | fs/lockd/svc.c | 1 | ||||
-rw-r--r-- | fs/nfs/callback.c | 1 | ||||
-rw-r--r-- | fs/nfsd/nfssvc.c | 3 | ||||
-rw-r--r-- | include/linux/sunrpc/svc.h | 15 | ||||
-rw-r--r-- | net/sunrpc/svc.c | 85 |
5 files changed, 73 insertions, 32 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 75415b21efda..96bb74c919f9 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -809,4 +809,5 @@ static struct svc_program nlmsvc_program = { | |||
809 | .pg_stats = &nlmsvc_stats, /* stats table */ | 809 | .pg_stats = &nlmsvc_stats, /* stats table */ |
810 | .pg_authenticate = &lockd_authenticate, /* export authentication */ | 810 | .pg_authenticate = &lockd_authenticate, /* export authentication */ |
811 | .pg_init_request = svc_generic_init_request, | 811 | .pg_init_request = svc_generic_init_request, |
812 | .pg_rpcbind_set = svc_generic_rpcbind_set, | ||
812 | }; | 813 | }; |
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index a9510374bad7..15c9575e0e7a 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -458,4 +458,5 @@ static struct svc_program nfs4_callback_program = { | |||
458 | .pg_stats = &nfs4_callback_stats, | 458 | .pg_stats = &nfs4_callback_stats, |
459 | .pg_authenticate = nfs_callback_authenticate, | 459 | .pg_authenticate = nfs_callback_authenticate, |
460 | .pg_init_request = svc_generic_init_request, | 460 | .pg_init_request = svc_generic_init_request, |
461 | .pg_rpcbind_set = svc_generic_rpcbind_set, | ||
461 | }; | 462 | }; |
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index e26762e84798..6a52400c85e0 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
@@ -87,6 +87,7 @@ static struct svc_program nfsd_acl_program = { | |||
87 | .pg_stats = &nfsd_acl_svcstats, | 87 | .pg_stats = &nfsd_acl_svcstats, |
88 | .pg_authenticate = &svc_set_client, | 88 | .pg_authenticate = &svc_set_client, |
89 | .pg_init_request = svc_generic_init_request, | 89 | .pg_init_request = svc_generic_init_request, |
90 | .pg_rpcbind_set = svc_generic_rpcbind_set, | ||
90 | }; | 91 | }; |
91 | 92 | ||
92 | static struct svc_stat nfsd_acl_svcstats = { | 93 | static struct svc_stat nfsd_acl_svcstats = { |
@@ -120,7 +121,7 @@ struct svc_program nfsd_program = { | |||
120 | .pg_stats = &nfsd_svcstats, /* version table */ | 121 | .pg_stats = &nfsd_svcstats, /* version table */ |
121 | .pg_authenticate = &svc_set_client, /* export authentication */ | 122 | .pg_authenticate = &svc_set_client, /* export authentication */ |
122 | .pg_init_request = svc_generic_init_request, | 123 | .pg_init_request = svc_generic_init_request, |
123 | 124 | .pg_rpcbind_set = svc_generic_rpcbind_set, | |
124 | }; | 125 | }; |
125 | 126 | ||
126 | static bool nfsd_supported_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1] = { | 127 | static bool nfsd_supported_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1] = { |
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index f43d5765acff..1afe38eb33f7 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h | |||
@@ -410,6 +410,11 @@ struct svc_program { | |||
410 | __be32 (*pg_init_request)(struct svc_rqst *, | 410 | __be32 (*pg_init_request)(struct svc_rqst *, |
411 | const struct svc_program *, | 411 | const struct svc_program *, |
412 | struct svc_process_info *); | 412 | struct svc_process_info *); |
413 | int (*pg_rpcbind_set)(struct net *net, | ||
414 | const struct svc_program *, | ||
415 | u32 version, int family, | ||
416 | unsigned short proto, | ||
417 | unsigned short port); | ||
413 | }; | 418 | }; |
414 | 419 | ||
415 | /* | 420 | /* |
@@ -522,6 +527,16 @@ __be32 svc_return_autherr(struct svc_rqst *rqstp, __be32 auth_err); | |||
522 | __be32 svc_generic_init_request(struct svc_rqst *rqstp, | 527 | __be32 svc_generic_init_request(struct svc_rqst *rqstp, |
523 | const struct svc_program *progp, | 528 | const struct svc_program *progp, |
524 | struct svc_process_info *procinfo); | 529 | struct svc_process_info *procinfo); |
530 | int svc_generic_rpcbind_set(struct net *net, | ||
531 | const struct svc_program *progp, | ||
532 | u32 version, int family, | ||
533 | unsigned short proto, | ||
534 | unsigned short port); | ||
535 | int svc_rpcbind_set_version(struct net *net, | ||
536 | const struct svc_program *progp, | ||
537 | u32 version, int family, | ||
538 | unsigned short proto, | ||
539 | unsigned short port); | ||
525 | 540 | ||
526 | #define RPC_MAX_ADDRBUFLEN (63U) | 541 | #define RPC_MAX_ADDRBUFLEN (63U) |
527 | 542 | ||
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 791c8076793f..2be827820247 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -993,6 +993,58 @@ static int __svc_register(struct net *net, const char *progname, | |||
993 | return error; | 993 | return error; |
994 | } | 994 | } |
995 | 995 | ||
996 | int svc_rpcbind_set_version(struct net *net, | ||
997 | const struct svc_program *progp, | ||
998 | u32 version, int family, | ||
999 | unsigned short proto, | ||
1000 | unsigned short port) | ||
1001 | { | ||
1002 | dprintk("svc: svc_register(%sv%d, %s, %u, %u)\n", | ||
1003 | progp->pg_name, version, | ||
1004 | proto == IPPROTO_UDP? "udp" : "tcp", | ||
1005 | port, family); | ||
1006 | |||
1007 | return __svc_register(net, progp->pg_name, progp->pg_prog, | ||
1008 | version, family, proto, port); | ||
1009 | |||
1010 | } | ||
1011 | EXPORT_SYMBOL_GPL(svc_rpcbind_set_version); | ||
1012 | |||
1013 | int svc_generic_rpcbind_set(struct net *net, | ||
1014 | const struct svc_program *progp, | ||
1015 | u32 version, int family, | ||
1016 | unsigned short proto, | ||
1017 | unsigned short port) | ||
1018 | { | ||
1019 | const struct svc_version *vers = progp->pg_vers[version]; | ||
1020 | int error; | ||
1021 | |||
1022 | if (vers == NULL) | ||
1023 | return 0; | ||
1024 | |||
1025 | if (vers->vs_hidden) { | ||
1026 | dprintk("svc: svc_register(%sv%d, %s, %u, %u)" | ||
1027 | " (but not telling portmap)\n", | ||
1028 | progp->pg_name, version, | ||
1029 | proto == IPPROTO_UDP? "udp" : "tcp", | ||
1030 | port, family); | ||
1031 | return 0; | ||
1032 | } | ||
1033 | |||
1034 | /* | ||
1035 | * Don't register a UDP port if we need congestion | ||
1036 | * control. | ||
1037 | */ | ||
1038 | if (vers->vs_need_cong_ctrl && proto == IPPROTO_UDP) | ||
1039 | return 0; | ||
1040 | |||
1041 | error = svc_rpcbind_set_version(net, progp, version, | ||
1042 | family, proto, port); | ||
1043 | |||
1044 | return (vers->vs_rpcb_optnl) ? 0 : error; | ||
1045 | } | ||
1046 | EXPORT_SYMBOL_GPL(svc_generic_rpcbind_set); | ||
1047 | |||
996 | /** | 1048 | /** |
997 | * svc_register - register an RPC service with the local portmapper | 1049 | * svc_register - register an RPC service with the local portmapper |
998 | * @serv: svc_serv struct for the service to register | 1050 | * @serv: svc_serv struct for the service to register |
@@ -1008,7 +1060,6 @@ int svc_register(const struct svc_serv *serv, struct net *net, | |||
1008 | const unsigned short port) | 1060 | const unsigned short port) |
1009 | { | 1061 | { |
1010 | struct svc_program *progp; | 1062 | struct svc_program *progp; |
1011 | const struct svc_version *vers; | ||
1012 | unsigned int i; | 1063 | unsigned int i; |
1013 | int error = 0; | 1064 | int error = 0; |
1014 | 1065 | ||
@@ -1018,37 +1069,9 @@ int svc_register(const struct svc_serv *serv, struct net *net, | |||
1018 | 1069 | ||
1019 | for (progp = serv->sv_program; progp; progp = progp->pg_next) { | 1070 | for (progp = serv->sv_program; progp; progp = progp->pg_next) { |
1020 | for (i = 0; i < progp->pg_nvers; i++) { | 1071 | for (i = 0; i < progp->pg_nvers; i++) { |
1021 | vers = progp->pg_vers[i]; | ||
1022 | if (vers == NULL) | ||
1023 | continue; | ||
1024 | |||
1025 | dprintk("svc: svc_register(%sv%d, %s, %u, %u)%s\n", | ||
1026 | progp->pg_name, | ||
1027 | i, | ||
1028 | proto == IPPROTO_UDP? "udp" : "tcp", | ||
1029 | port, | ||
1030 | family, | ||
1031 | vers->vs_hidden ? | ||
1032 | " (but not telling portmap)" : ""); | ||
1033 | |||
1034 | if (vers->vs_hidden) | ||
1035 | continue; | ||
1036 | |||
1037 | /* | ||
1038 | * Don't register a UDP port if we need congestion | ||
1039 | * control. | ||
1040 | */ | ||
1041 | if (vers->vs_need_cong_ctrl && proto == IPPROTO_UDP) | ||
1042 | continue; | ||
1043 | |||
1044 | error = __svc_register(net, progp->pg_name, progp->pg_prog, | ||
1045 | i, family, proto, port); | ||
1046 | |||
1047 | if (vers->vs_rpcb_optnl) { | ||
1048 | error = 0; | ||
1049 | continue; | ||
1050 | } | ||
1051 | 1072 | ||
1073 | error = progp->pg_rpcbind_set(net, progp, i, | ||
1074 | family, proto, port); | ||
1052 | if (error < 0) { | 1075 | if (error < 0) { |
1053 | printk(KERN_WARNING "svc: failed to register " | 1076 | printk(KERN_WARNING "svc: failed to register " |
1054 | "%sv%u RPC service (errno %d).\n", | 1077 | "%sv%u RPC service (errno %d).\n", |