aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svc.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2009-03-18 20:47:29 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-03-28 15:58:07 -0400
commitd5a8620f7c8a5bcade730e2fa1224191f289fb00 (patch)
tree40fc44449ff6553af283df00f804bc7d4ce356af /net/sunrpc/svc.c
parent1673d0de40ab46cac3b456ad50e1c8d6a31bfd66 (diff)
SUNRPC: Simplify svc_unregister()
Our initial implementation of svc_unregister() assumed that PMAP_UNSET cleared all rpcbind registrations for a [program, version] tuple. However, we now have evidence that PMAP_UNSET clears only "inet" entries, and not "inet6" entries, in the rpcbind database. For backwards compatibility with the legacy portmapper, the svc_unregister() function also must work if user space doesn't support rpcbind version 4 at all. Thus we'll send an rpcbind v4 UNSET, and if that fails, we'll send a PMAP_UNSET. This simplifies the code in svc_unregister() and provides better backwards compatibility with legacy user space that does not support rpcbind version 4. We can get rid of the conditional compilation in here as well. This patch is part of a series that addresses http://bugzilla.kernel.org/show_bug.cgi?id=12256 Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/svc.c')
-rw-r--r--net/sunrpc/svc.c35
1 files changed, 14 insertions, 21 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 17e0d7265dfd..bd0ee312dac9 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -896,38 +896,31 @@ int svc_register(const struct svc_serv *serv, const int family,
896 return error; 896 return error;
897} 897}
898 898
899#ifdef CONFIG_SUNRPC_REGISTER_V4 899/*
900 900 * If user space is running rpcbind, it should take the v4 UNSET
901 * and clear everything for this [program, version]. If user space
902 * is running portmap, it will reject the v4 UNSET, but won't have
903 * any "inet6" entries anyway. So a PMAP_UNSET should be sufficient
904 * in this case to clear all existing entries for [program, version].
905 */
901static void __svc_unregister(const u32 program, const u32 version, 906static void __svc_unregister(const u32 program, const u32 version,
902 const char *progname) 907 const char *progname)
903{ 908{
904 struct sockaddr_in6 sin6 = {
905 .sin6_family = AF_INET6,
906 .sin6_addr = IN6ADDR_ANY_INIT,
907 .sin6_port = 0,
908 };
909 int error; 909 int error;
910 910
911 error = rpcb_v4_register(program, version, 911 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 912
919static void __svc_unregister(const u32 program, const u32 version, 913 /*
920 const char *progname) 914 * User space didn't support rpcbind v4, so retry this
921{ 915 * request with the legacy rpcbind v2 protocol.
922 int error; 916 */
917 if (error == -EPROTONOSUPPORT)
918 error = rpcb_register(program, version, 0, 0);
923 919
924 error = rpcb_register(program, version, 0, 0);
925 dprintk("svc: %s(%sv%u), error %d\n", 920 dprintk("svc: %s(%sv%u), error %d\n",
926 __func__, progname, version, error); 921 __func__, progname, version, error);
927} 922}
928 923
929#endif /* CONFIG_SUNRPC_REGISTER_V4 */
930
931/* 924/*
932 * All netids, bind addresses and ports registered for [program, version] 925 * All netids, bind addresses and ports registered for [program, version]
933 * are removed from the local rpcbind database (if the service is not 926 * are removed from the local rpcbind database (if the service is not