Linux NFS development
 help / color / mirror / Atom feed
* [PATCH 00/40] Proposed patches for 2.6.30
@ 2009-03-12 16:06 Chuck Lever
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
       [not found] ` <20090312161129.16019.26502.stgit@ingres.1015granger.net>
  0 siblings, 2 replies; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:06 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

Hi Bruce, Trond-

Here are the IPv6-related patches I'd like to propose for inclusion
in 2.6.30.  These include fixes for IPv6 support in the kernel's
rpcbind client, in lockd, and in the NFSv4 callback server, plus a
lot of clean up.  Many of these have had some revision since the
patches you [Bruce] looked at yesterday (which were sent a couple of
weeks ago).

I'm reserving the final few NFSD IPv6 patches until we have user space
IPv6 support on the server side and we can start testing.

Note that there are two patches Trond sent for 2.6.29-rc that don't
seem to be in Linus' tree yet.  That may cause a little heartburn if
you try to add these to your tree today.  However, since 2.6.30 is
imminent, I thought it best to present these for review now.

The main feature of these patches is that the single address family
listener strategy is abandoned in favor of using separate listeners
for AF_INET and AF_INET6.  This has two main benefits:

 1.  Kernel RPC servers no longer have to deal with mapped v4 addresses
     coming from the network layer, and

 2.  PF_INET listeners are always started; PF_INET6 listeners are
     started if possible.  This allows people to disable IPv6
     support cleanly by blacklisting ipv6.ko, but should have no
     affect on normal IPv4 operation.

This new scheme can be used to add support for additional address
families, unlike the single-listener-per-af scheme.

We also get rid of CONFIG_SUNRPC_REGISTER_V4 entirely.  The kernel can
handle either portmapper or rpcbind in user space automatically now.

These have seen light testing, and previous versions of this patch set
have been exercised at Connectathon.

---

Chuck Lever (40):
      NFSD: Prevent buffer overflow in write_recoverydir()
      NFSD: Prevent buffer overflow in write_leasetime()
      NFSD: Prevent buffer overflow in write_maxblksize()
      NFSD: Prevent buffer overflow in write_versions()
      NFSD: Prevent buffer overflow in write_threads()
      NFSD: Support IPv6 addresses in write_failover_ip()
      NFS: Move NFS client's IP address parser to nfs_common/
      SUNRPC: Clean up one_sock_name()
      SUNRPC: Support PF_INET6 in one_sock_name()
      SUNRPC: Switch one_sock_name() to use snprintf()
      SUNRPC: pass buffer size to svc_sock_names()
      SUNRPC: pass buffer size to svc_addsock()
      NFSD: Prevent a buffer overflow in svc_xprt_names()
      NFSD: move lockd_up() before svc_addsock()
      NFSD: Finish refactoring __write_ports()
      NFSD: Note an additional requirement when passing TCP sockets to portlist
      NFSD: Refactor socket creation out of __write_ports()
      NFSD: Refactor portlist socket closing into a helper
      NFSD: Refactor transport addition out of __write_ports()
      NFSD: Refactor transport removal out of __write_ports()
      NFS: Start PF_INET6 callback listener only if IPv6 support is available
      lockd: Start PF_INET6 listener only if IPv6 support is available
      SUNRPC: Remove CONFIG_SUNRPC_REGISTER_V4
      SUNRPC: rpcb_register() should handle errors silently
      SUNRPC: Simplify kernel RPC service registration
      SUNRPC: Simplify svc_unregister()
      SUNRPC: Allow callers to pass rpcb_v4_register a NULL address
      SUNRPC: rpcbind actually interprets r_owner string
      SUNRPC: Clean up address type casts in rpcb_v4_register()
      SUNRPC: Don't return EPROTONOSUPPORT in svc_register()'s helpers
      SUNRPC: Use IPv4 loopback for registering AF_INET6 kernel RPC services
      SUNRPC: Set IPV6ONLY flag on PF_INET6 RPC listener sockets
      NFS: Revert creation of IPv6 listeners for lockd and NFSv4 callbacks
      SUNRPC: Remove @family argument from svc_create() and svc_create_pooled()
      SUNRPC: Change svc_create_xprt() to take a @family argument
      SUNRPC: svc_setup_socket() gets protocol family from socket
      SUNRPC: Pass a family argument to svc_register()
      SUNRPC: Clean up svc_find_xprt() calling sequence
      SUNRPC: Clean up static inline functions in svc_xprt.h
      SUNRPC: Fix return type of svc_addr_len()


 fs/lockd/clntlock.c                      |   51 -----
 fs/lockd/svc.c                           |   42 ++--
 fs/nfs/callback.c                        |   31 ++-
 fs/nfs/callback.h                        |    1 
 fs/nfs/client.c                          |   69 +++----
 fs/nfs/internal.h                        |    3 
 fs/nfs/nfs4namespace.c                   |    2 
 fs/nfs/nfs4state.c                       |   10 +
 fs/nfs/super.c                           |  121 ------------
 fs/nfs_common/Makefile                   |    1 
 fs/nfs_common/nfs_addr_parse.c           |  151 +++++++++++++++
 fs/nfsd/nfsctl.c                         |  298 +++++++++++++++++-------------
 fs/nfsd/nfssvc.c                         |    5 -
 include/linux/nfs_addr_parse.h           |   29 +++
 include/linux/sunrpc/svc.h               |    9 -
 include/linux/sunrpc/svc_xprt.h          |   57 +++---
 include/linux/sunrpc/svcsock.h           |    7 +
 net/sunrpc/Kconfig                       |   22 --
 net/sunrpc/rpcb_clnt.c                   |   92 +++++----
 net/sunrpc/svc.c                         |  158 +++++++---------
 net/sunrpc/svc_xprt.c                    |   87 ++++++---
 net/sunrpc/svcsock.c                     |   94 +++++++--
 net/sunrpc/xprtrdma/svc_rdma_transport.c |   16 +-
 23 files changed, 743 insertions(+), 613 deletions(-)
 create mode 100644 fs/nfs_common/nfs_addr_parse.c
 create mode 100644 include/linux/nfs_addr_parse.h

-- 
Chuck Lever

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 01/40] SUNRPC: Fix return type of svc_addr_len()
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2009-03-12 16:07   ` Chuck Lever
       [not found]     ` <20090312160706.16019.81338.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2009-03-12 16:07   ` [PATCH 02/40] SUNRPC: Clean up static inline functions in svc_xprt.h Chuck Lever
                     ` (12 subsequent siblings)
  13 siblings, 1 reply; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:07 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

The svc_addr_len() helper function can return a negative errno value,
but its return type is size_t, which is unsigned.

The RDMA transport code passes this return value directly to memset(),
without checking first if it's negative.  This could cause memset() to
clobber a large piece of memory if svc_addr_len() has returned an
error.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 include/linux/sunrpc/svc_xprt.h          |    3 ++-
 net/sunrpc/xprtrdma/svc_rdma_transport.c |   16 ++++++++++++++--
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index 0127dac..c2aa8cd 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -113,7 +113,7 @@ static inline unsigned short svc_addr_port(struct sockaddr *sa)
 	return ret;
 }
 
-static inline size_t svc_addr_len(struct sockaddr *sa)
+static inline int svc_addr_len(const struct sockaddr *sa)
 {
 	switch (sa->sa_family) {
 	case AF_INET:
@@ -121,6 +121,7 @@ static inline size_t svc_addr_len(struct sockaddr *sa)
 	case AF_INET6:
 		return sizeof(struct sockaddr_in6);
 	}
+
 	return -EAFNOSUPPORT;
 }
 
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 3d810e7..d1ec6f9 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -546,6 +546,7 @@ static void handle_connect_req(struct rdma_cm_id *new_cma_id, size_t client_ird)
 	struct svcxprt_rdma *listen_xprt = new_cma_id->context;
 	struct svcxprt_rdma *newxprt;
 	struct sockaddr *sa;
+	int len;
 
 	/* Create a new transport */
 	newxprt = rdma_create_xprt(listen_xprt->sc_xprt.xpt_server, 0);
@@ -563,9 +564,20 @@ static void handle_connect_req(struct rdma_cm_id *new_cma_id, size_t client_ird)
 
 	/* Set the local and remote addresses in the transport */
 	sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.dst_addr;
-	svc_xprt_set_remote(&newxprt->sc_xprt, sa, svc_addr_len(sa));
+	len = svc_addr_len(sa);
+	if (len < 0) {
+		dprintk("svcrdma: dst_addr has a bad address family\n");
+		return;
+	}
+	svc_xprt_set_remote(&newxprt->sc_xprt, sa, len);
+
 	sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.src_addr;
-	svc_xprt_set_local(&newxprt->sc_xprt, sa, svc_addr_len(sa));
+	len = svc_addr_len(sa);
+	if (len < 0) {
+		dprintk("svcrdma: src_addr has a bad address family\n");
+		return;
+	}
+	svc_xprt_set_local(&newxprt->sc_xprt, sa, len);
 
 	/*
 	 * Enqueue the new transport on the accept queue of the listening


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 02/40] SUNRPC: Clean up static inline functions in svc_xprt.h
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2009-03-12 16:07   ` [PATCH 01/40] SUNRPC: Fix return type of svc_addr_len() Chuck Lever
@ 2009-03-12 16:07   ` Chuck Lever
       [not found]     ` <20090312160713.16019.56290.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2009-03-12 16:07   ` [PATCH 03/40] SUNRPC: Clean up svc_find_xprt() calling sequence Chuck Lever
                     ` (11 subsequent siblings)
  13 siblings, 1 reply; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:07 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

Clean up:  Enable the use of const arguments in higher level svc_ APIs
by adding const to the arguments of the helper functions in svc_xprt.h

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 include/linux/sunrpc/svc_xprt.h |   46 ++++++++++++++++++++++-----------------
 1 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index c2aa8cd..ee21e8a 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -88,29 +88,32 @@ static inline void svc_xprt_get(struct svc_xprt *xprt)
 	kref_get(&xprt->xpt_ref);
 }
 static inline void svc_xprt_set_local(struct svc_xprt *xprt,
-				      struct sockaddr *sa, int salen)
+				      const struct sockaddr *sa,
+				      const size_t salen)
 {
 	memcpy(&xprt->xpt_local, sa, salen);
 	xprt->xpt_locallen = salen;
 }
 static inline void svc_xprt_set_remote(struct svc_xprt *xprt,
-				       struct sockaddr *sa, int salen)
+				       const struct sockaddr *sa,
+				       const size_t salen)
 {
 	memcpy(&xprt->xpt_remote, sa, salen);
 	xprt->xpt_remotelen = salen;
 }
-static inline unsigned short svc_addr_port(struct sockaddr *sa)
+static inline unsigned short svc_addr_port(const struct sockaddr *sa)
 {
-	unsigned short ret = 0;
+	const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
+	const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
+
 	switch (sa->sa_family) {
 	case AF_INET:
-		ret = ntohs(((struct sockaddr_in *)sa)->sin_port);
-		break;
+		return ntohs(sin->sin_port);
 	case AF_INET6:
-		ret = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
-		break;
+		return ntohs(sin6->sin6_port);
 	}
-	return ret;
+
+	return 0;
 }
 
 static inline int svc_addr_len(const struct sockaddr *sa)
@@ -125,36 +128,39 @@ static inline int svc_addr_len(const struct sockaddr *sa)
 	return -EAFNOSUPPORT;
 }
 
-static inline unsigned short svc_xprt_local_port(struct svc_xprt *xprt)
+static inline unsigned short svc_xprt_local_port(const struct svc_xprt *xprt)
 {
-	return svc_addr_port((struct sockaddr *)&xprt->xpt_local);
+	return svc_addr_port((const struct sockaddr *)&xprt->xpt_local);
 }
 
-static inline unsigned short svc_xprt_remote_port(struct svc_xprt *xprt)
+static inline unsigned short svc_xprt_remote_port(const struct svc_xprt *xprt)
 {
-	return svc_addr_port((struct sockaddr *)&xprt->xpt_remote);
+	return svc_addr_port((const struct sockaddr *)&xprt->xpt_remote);
 }
 
-static inline char *__svc_print_addr(struct sockaddr *addr,
-				     char *buf, size_t len)
+static inline char *__svc_print_addr(const struct sockaddr *addr,
+				     char *buf, const size_t len)
 {
+	const struct sockaddr_in *sin = (const struct sockaddr_in *)addr;
+	const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)addr;
+
 	switch (addr->sa_family) {
 	case AF_INET:
-		snprintf(buf, len, "%pI4, port=%u",
-			&((struct sockaddr_in *)addr)->sin_addr,
-			ntohs(((struct sockaddr_in *) addr)->sin_port));
+		snprintf(buf, len, "%pI4, port=%u", &sin->sin_addr,
+			ntohs(sin->sin_port));
 		break;
 
 	case AF_INET6:
 		snprintf(buf, len, "%pI6, port=%u",
-			 &((struct sockaddr_in6 *)addr)->sin6_addr,
-			ntohs(((struct sockaddr_in6 *) addr)->sin6_port));
+			 &sin6->sin6_addr,
+			ntohs(sin6->sin6_port));
 		break;
 
 	default:
 		snprintf(buf, len, "unknown address type: %d", addr->sa_family);
 		break;
 	}
+
 	return buf;
 }
 #endif /* SUNRPC_SVC_XPRT_H */


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 03/40] SUNRPC: Clean up svc_find_xprt() calling sequence
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2009-03-12 16:07   ` [PATCH 01/40] SUNRPC: Fix return type of svc_addr_len() Chuck Lever
  2009-03-12 16:07   ` [PATCH 02/40] SUNRPC: Clean up static inline functions in svc_xprt.h Chuck Lever
@ 2009-03-12 16:07   ` Chuck Lever
       [not found]     ` <20090312160721.16019.89653.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2009-03-12 16:07   ` [PATCH 04/40] SUNRPC: Pass a family argument to svc_register() Chuck Lever
                     ` (10 subsequent siblings)
  13 siblings, 1 reply; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:07 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

Clean up: add documentating comment and use appropriate data types for
svc_find_xprt()'s arguments.

This also eliminates a mixed sign comparison: @port was an int, while
the return value of svc_xprt_local_port() is an unsigned short.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 include/linux/sunrpc/svc_xprt.h |    3 ++-
 net/sunrpc/svc_xprt.c           |   16 +++++++++++-----
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index ee21e8a..167e4b5 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -80,7 +80,8 @@ void	svc_close_xprt(struct svc_xprt *xprt);
 void	svc_delete_xprt(struct svc_xprt *xprt);
 int	svc_port_is_privileged(struct sockaddr *sin);
 int	svc_print_xprts(char *buf, int maxlen);
-struct	svc_xprt *svc_find_xprt(struct svc_serv *, char *, int, int);
+struct	svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
+			const sa_family_t af, const unsigned short port);
 int	svc_xprt_names(struct svc_serv *serv, char *buf, int buflen);
 
 static inline void svc_xprt_get(struct svc_xprt *xprt)
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index e588df5..c947c93 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -1033,7 +1033,13 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt)
 	return dr;
 }
 
-/*
+/**
+ * svc_find_xprt - find an RPC transport instance
+ * @serv: pointer to svc_serv to search
+ * @xcl_name: C string containing transport's class name
+ * @af: Address family of transport's local address
+ * @port: transport's IP port number
+ *
  * Return the transport instance pointer for the endpoint accepting
  * connections/peer traffic from the specified transport class,
  * address family and port.
@@ -1042,14 +1048,14 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt)
  * wild-card, and will result in matching the first transport in the
  * service's list that has a matching class name.
  */
-struct svc_xprt *svc_find_xprt(struct svc_serv *serv, char *xcl_name,
-			       int af, int port)
+struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
+			       const sa_family_t af, const unsigned short port)
 {
 	struct svc_xprt *xprt;
 	struct svc_xprt *found = NULL;
 
 	/* Sanity check the args */
-	if (!serv || !xcl_name)
+	if (serv == NULL || xcl_name == NULL)
 		return found;
 
 	spin_lock_bh(&serv->sv_lock);
@@ -1058,7 +1064,7 @@ struct svc_xprt *svc_find_xprt(struct svc_serv *serv, char *xcl_name,
 			continue;
 		if (af != AF_UNSPEC && af != xprt->xpt_local.ss_family)
 			continue;
-		if (port && port != svc_xprt_local_port(xprt))
+		if (port != 0 && port != svc_xprt_local_port(xprt))
 			continue;
 		found = xprt;
 		svc_xprt_get(xprt);


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 04/40] SUNRPC: Pass a family argument to svc_register()
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (2 preceding siblings ...)
  2009-03-12 16:07   ` [PATCH 03/40] SUNRPC: Clean up svc_find_xprt() calling sequence Chuck Lever
@ 2009-03-12 16:07   ` Chuck Lever
  2009-03-12 16:07   ` [PATCH 05/40] SUNRPC: svc_setup_socket() gets protocol family from socket Chuck Lever
                     ` (9 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:07 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

The sv_family field is going away.  Instead of using sv_family, have
the svc_register() function take a protocol family argument.

Since this argument represents a protocol family, and not an address
family, this argument takes an int, as this is what is passed to
sock_create_kern().  Also make sure svc_register's helpers are
checking for PF_FOO instead of AF_FOO.  The value of [AP]F_FOO are
equivalent; this is simply a symbolic change to reflect the semantics
of the value stored in that variable.

sock_create_kern() should return EPFNOSUPPORT if the passed-in
protocol family isn't supported, but it uses EAFNOSUPPORT for this
case.  We will stick with that tradition here, as svc_register()
is called by the RPC server in the same path as sock_create_kern().

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 include/linux/sunrpc/svc.h |    4 ++--
 net/sunrpc/svc.c           |   21 +++++++++++----------
 net/sunrpc/svcsock.c       |    2 +-
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 3435d24..1f18fc7 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -396,8 +396,8 @@ struct svc_serv *  svc_create_pooled(struct svc_program *, unsigned int,
 int		   svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
 void		   svc_destroy(struct svc_serv *);
 int		   svc_process(struct svc_rqst *);
-int		   svc_register(const struct svc_serv *, const unsigned short,
-				const unsigned short);
+int		   svc_register(const struct svc_serv *, const int,
+				const unsigned short, const unsigned short);
 
 void		   svc_wake_up(struct svc_serv *);
 void		   svc_reserve(struct svc_rqst *rqstp, int space);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index c51fed4..41bc36e 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -800,17 +800,17 @@ static int __svc_rpcb_register6(const u32 program, const u32 version,
  * if any error occurs.
  */
 static int __svc_register(const u32 program, const u32 version,
-			  const sa_family_t family,
+			  const int family,
 			  const unsigned short protocol,
 			  const unsigned short port)
 {
 	int error;
 
 	switch (family) {
-	case AF_INET:
+	case PF_INET:
 		return __svc_rpcb_register4(program, version,
 						protocol, port);
-	case AF_INET6:
+	case PF_INET6:
 		error = __svc_rpcb_register6(program, version,
 						protocol, port);
 		if (error < 0)
@@ -840,11 +840,11 @@ static int __svc_register(const u32 program, const u32 version,
  * if any error occurs.
  */
 static int __svc_register(const u32 program, const u32 version,
-			  sa_family_t family,
+			  const int family,
 			  const unsigned short protocol,
 			  const unsigned short port)
 {
-	if (family != AF_INET)
+	if (family != PF_INET)
 		return -EAFNOSUPPORT;
 
 	return rpcb_register(program, version, protocol, port);
@@ -855,13 +855,14 @@ static int __svc_register(const u32 program, const u32 version,
 /**
  * svc_register - register an RPC service with the local portmapper
  * @serv: svc_serv struct for the service to register
+ * @family: protocol family of service's listener socket
  * @proto: transport protocol number to advertise
  * @port: port to advertise
  *
- * Service is registered for any address in serv's address family
+ * Service is registered for any address in the passed-in protocol family
  */
-int svc_register(const struct svc_serv *serv, const unsigned short proto,
-		 const unsigned short port)
+int svc_register(const struct svc_serv *serv, const int family,
+		 const unsigned short proto, const unsigned short port)
 {
 	struct svc_program	*progp;
 	unsigned int		i;
@@ -879,7 +880,7 @@ int svc_register(const struct svc_serv *serv, const unsigned short proto,
 					i,
 					proto == IPPROTO_UDP?  "udp" : "tcp",
 					port,
-					serv->sv_family,
+					family,
 					progp->pg_vers[i]->vs_hidden?
 						" (but not telling portmap)" : "");
 
@@ -887,7 +888,7 @@ int svc_register(const struct svc_serv *serv, const unsigned short proto,
 				continue;
 
 			error = __svc_register(progp->pg_prog, i,
-						serv->sv_family, proto, port);
+						family, proto, port);
 			if (error < 0)
 				break;
 		}
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 5763e64..d00583c 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1122,7 +1122,7 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
 
 	/* Register socket with portmapper */
 	if (*errp >= 0 && pmap_register)
-		*errp = svc_register(serv, inet->sk_protocol,
+		*errp = svc_register(serv, serv->sv_family, inet->sk_protocol,
 				     ntohs(inet_sk(inet)->sport));
 
 	if (*errp < 0) {


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 05/40] SUNRPC: svc_setup_socket() gets protocol family from socket
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (3 preceding siblings ...)
  2009-03-12 16:07   ` [PATCH 04/40] SUNRPC: Pass a family argument to svc_register() Chuck Lever
@ 2009-03-12 16:07   ` Chuck Lever
  2009-03-12 16:07   ` [PATCH 06/40] SUNRPC: Change svc_create_xprt() to take a @family argument Chuck Lever
                     ` (8 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:07 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

Since the sv_family field is going away, modify svc_setup_socket() to
extract the protocol family from the passed-in socket instead of from
the passed-in svc_serv struct.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 net/sunrpc/svcsock.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index d00583c..d00bc33 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1122,7 +1122,7 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
 
 	/* Register socket with portmapper */
 	if (*errp >= 0 && pmap_register)
-		*errp = svc_register(serv, serv->sv_family, inet->sk_protocol,
+		*errp = svc_register(serv, inet->sk_family, inet->sk_protocol,
 				     ntohs(inet_sk(inet)->sport));
 
 	if (*errp < 0) {
@@ -1145,13 +1145,13 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
 
 	/*
 	 * We start one listener per sv_serv.  We want AF_INET
-	 * requests to be automatically shunted to our AF_INET6
+	 * requests to be automatically shunted to our PF_INET6
 	 * listener using a mapped IPv4 address.  Make sure
 	 * no-one starts an equivalent IPv4 listener, which
 	 * would steal our incoming connections.
 	 */
 	val = 0;
-	if (serv->sv_family == AF_INET6)
+	if (inet->sk_family == PF_INET6)
 		kernel_setsockopt(sock, SOL_IPV6, IPV6_V6ONLY,
 					(char *)&val, sizeof(val));
 


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 06/40] SUNRPC: Change svc_create_xprt() to take a @family argument
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (4 preceding siblings ...)
  2009-03-12 16:07   ` [PATCH 05/40] SUNRPC: svc_setup_socket() gets protocol family from socket Chuck Lever
@ 2009-03-12 16:07   ` Chuck Lever
  2009-03-12 16:07   ` [PATCH 07/40] SUNRPC: Remove @family argument from svc_create() and svc_create_pooled() Chuck Lever
                     ` (7 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:07 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

The sv_family field is going away.  Pass a protocol family argument to
svc_create_xprt() instead of extracting the family from the passed-in
svc_serv struct.

Again, as this is a listener socket and not an address, we make this
new argument an "int" protocol family, instead of an "sa_family_t."

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/svc.c                  |    3 ++-
 fs/nfs/callback.c               |    4 ++--
 fs/nfsd/nfsctl.c                |    2 +-
 fs/nfsd/nfssvc.c                |    4 ++--
 include/linux/sunrpc/svc_xprt.h |    3 ++-
 net/sunrpc/svc_xprt.c           |   15 +++++++++------
 6 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 64f1c31..390c559 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -211,7 +211,8 @@ static int create_lockd_listener(struct svc_serv *serv, char *name,
 
 	xprt = svc_find_xprt(serv, name, 0, 0);
 	if (xprt == NULL)
-		return svc_create_xprt(serv, name, port, SVC_SOCK_DEFAULTS);
+		return svc_create_xprt(serv, name, nlmsvc_family,
+					port, SVC_SOCK_DEFAULTS);
 
 	svc_xprt_put(xprt);
 	return 0;
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 3e634f2..fb35cab 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -122,8 +122,8 @@ int nfs_callback_up(void)
 	if (!serv)
 		goto out_err;
 
-	ret = svc_create_xprt(serv, "tcp", nfs_callback_set_tcpport,
-			      SVC_SOCK_ANONYMOUS);
+	ret = svc_create_xprt(serv, "tcp", nfs_callback_family,
+				nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
 	if (ret <= 0)
 		goto out_err;
 	nfs_callback_tcpport = ret;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 3d93b20..817999e 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -941,7 +941,7 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size)
 			err = nfsd_create_serv();
 			if (!err) {
 				err = svc_create_xprt(nfsd_serv,
-						      transport, port,
+						      transport, PF_INET, port,
 						      SVC_SOCK_ANONYMOUS);
 				if (err == -ENOENT)
 					/* Give a reasonable perror msg for
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 07e4f5d..ab7f249 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -244,7 +244,7 @@ static int nfsd_init_socks(int port)
 	if (!list_empty(&nfsd_serv->sv_permsocks))
 		return 0;
 
-	error = svc_create_xprt(nfsd_serv, "udp", port,
+	error = svc_create_xprt(nfsd_serv, "udp", PF_INET, port,
 					SVC_SOCK_DEFAULTS);
 	if (error < 0)
 		return error;
@@ -253,7 +253,7 @@ static int nfsd_init_socks(int port)
 	if (error < 0)
 		return error;
 
-	error = svc_create_xprt(nfsd_serv, "tcp", port,
+	error = svc_create_xprt(nfsd_serv, "tcp", PF_INET, port,
 					SVC_SOCK_DEFAULTS);
 	if (error < 0)
 		return error;
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index 167e4b5..72c5e9c 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -71,7 +71,8 @@ int	svc_reg_xprt_class(struct svc_xprt_class *);
 void	svc_unreg_xprt_class(struct svc_xprt_class *);
 void	svc_xprt_init(struct svc_xprt_class *, struct svc_xprt *,
 		      struct svc_serv *);
-int	svc_create_xprt(struct svc_serv *, char *, unsigned short, int);
+int	svc_create_xprt(struct svc_serv *, const char *, const int,
+			const unsigned short, int);
 void	svc_xprt_enqueue(struct svc_xprt *xprt);
 void	svc_xprt_received(struct svc_xprt *);
 void	svc_xprt_put(struct svc_xprt *xprt);
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index c947c93..2819ee0 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -161,7 +161,9 @@ EXPORT_SYMBOL_GPL(svc_xprt_init);
 
 static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
 					 struct svc_serv *serv,
-					 unsigned short port, int flags)
+					 const int family,
+					 const unsigned short port,
+					 int flags)
 {
 	struct sockaddr_in sin = {
 		.sin_family		= AF_INET,
@@ -176,12 +178,12 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
 	struct sockaddr *sap;
 	size_t len;
 
-	switch (serv->sv_family) {
-	case AF_INET:
+	switch (family) {
+	case PF_INET:
 		sap = (struct sockaddr *)&sin;
 		len = sizeof(sin);
 		break;
-	case AF_INET6:
+	case PF_INET6:
 		sap = (struct sockaddr *)&sin6;
 		len = sizeof(sin6);
 		break;
@@ -192,7 +194,8 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
 	return xcl->xcl_ops->xpo_create(serv, sap, len, flags);
 }
 
-int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port,
+int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
+		    const int family, const unsigned short port,
 		    int flags)
 {
 	struct svc_xprt_class *xcl;
@@ -209,7 +212,7 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port,
 			goto err;
 
 		spin_unlock(&svc_xprt_class_lock);
-		newxprt = __svc_xpo_create(xcl, serv, port, flags);
+		newxprt = __svc_xpo_create(xcl, serv, family, port, flags);
 		if (IS_ERR(newxprt)) {
 			module_put(xcl->xcl_owner);
 			return PTR_ERR(newxprt);


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 07/40] SUNRPC: Remove @family argument from svc_create() and svc_create_pooled()
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (5 preceding siblings ...)
  2009-03-12 16:07   ` [PATCH 06/40] SUNRPC: Change svc_create_xprt() to take a @family argument Chuck Lever
@ 2009-03-12 16:07   ` Chuck Lever
  2009-03-12 16:07   ` [PATCH 08/40] NFS: Revert creation of IPv6 listeners for lockd and NFSv4 callbacks Chuck Lever
                     ` (6 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:07 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

Since an RPC service listener's protocol family is specified now via
svc_create_xprt(), it no longer needs to be passed to svc_create() or
svc_create_pooled().  Remove that argument from the synopsis of those
functions, and remove the sv_family field from the svc_serv struct.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/svc.c             |    2 +-
 fs/nfs/callback.c          |    3 +--
 fs/nfsd/nfssvc.c           |    1 -
 include/linux/sunrpc/svc.h |    5 ++---
 net/sunrpc/svc.c           |   11 +++++------
 5 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 390c559..d309200 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -275,7 +275,7 @@ int lockd_up(void)
 			"lockd_up: no pid, %d users??\n", nlmsvc_users);
 
 	error = -ENOMEM;
-	serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, nlmsvc_family, NULL);
+	serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
 	if (!serv) {
 		printk(KERN_WARNING "lockd_up: create service failed\n");
 		goto out;
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index fb35cab..ddf4b4a 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -116,8 +116,7 @@ int nfs_callback_up(void)
 	mutex_lock(&nfs_callback_mutex);
 	if (nfs_callback_info.users++ || nfs_callback_info.task != NULL)
 		goto out;
-	serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE,
-				nfs_callback_family, NULL);
+	serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
 	ret = -ENOMEM;
 	if (!serv)
 		goto out_err;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index ab7f249..bc3567b 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -229,7 +229,6 @@ int nfsd_create_serv(void)
 
 	atomic_set(&nfsd_busy, 0);
 	nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
-				      AF_INET,
 				      nfsd_last_thread, nfsd, THIS_MODULE);
 	if (nfsd_serv == NULL)
 		err = -ENOMEM;
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 1f18fc7..d3a4c02 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -69,7 +69,6 @@ struct svc_serv {
 	struct list_head	sv_tempsocks;	/* all temporary sockets */
 	int			sv_tmpcnt;	/* count of temporary sockets */
 	struct timer_list	sv_temptimer;	/* timer for aging temporary sockets */
-	sa_family_t		sv_family;	/* listener's address family */
 
 	char *			sv_name;	/* service name */
 
@@ -385,13 +384,13 @@ struct svc_procedure {
 /*
  * Function prototypes.
  */
-struct svc_serv *svc_create(struct svc_program *, unsigned int, sa_family_t,
+struct svc_serv *svc_create(struct svc_program *, unsigned int,
 			    void (*shutdown)(struct svc_serv *));
 struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
 					struct svc_pool *pool);
 void		   svc_exit_thread(struct svc_rqst *);
 struct svc_serv *  svc_create_pooled(struct svc_program *, unsigned int,
-			sa_family_t, void (*shutdown)(struct svc_serv *),
+			void (*shutdown)(struct svc_serv *),
 			svc_thread_fn, struct module *);
 int		   svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
 void		   svc_destroy(struct svc_serv *);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 41bc36e..d72ff44 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)
  */
 static struct svc_serv *
 __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
-	   sa_family_t family, void (*shutdown)(struct svc_serv *serv))
+	     void (*shutdown)(struct svc_serv *serv))
 {
 	struct svc_serv	*serv;
 	unsigned int vers;
@@ -368,7 +368,6 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
 
 	if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL)))
 		return NULL;
-	serv->sv_family    = family;
 	serv->sv_name      = prog->pg_name;
 	serv->sv_program   = prog;
 	serv->sv_nrthreads = 1;
@@ -427,21 +426,21 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
 
 struct svc_serv *
 svc_create(struct svc_program *prog, unsigned int bufsize,
-		sa_family_t family, void (*shutdown)(struct svc_serv *serv))
+	   void (*shutdown)(struct svc_serv *serv))
 {
-	return __svc_create(prog, bufsize, /*npools*/1, family, shutdown);
+	return __svc_create(prog, bufsize, /*npools*/1, shutdown);
 }
 EXPORT_SYMBOL_GPL(svc_create);
 
 struct svc_serv *
 svc_create_pooled(struct svc_program *prog, unsigned int bufsize,
-		  sa_family_t family, void (*shutdown)(struct svc_serv *serv),
+		  void (*shutdown)(struct svc_serv *serv),
 		  svc_thread_fn func, struct module *mod)
 {
 	struct svc_serv *serv;
 	unsigned int npools = svc_pool_map_get();
 
-	serv = __svc_create(prog, bufsize, npools, family, shutdown);
+	serv = __svc_create(prog, bufsize, npools, shutdown);
 
 	if (serv != NULL) {
 		serv->sv_function = func;


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 08/40] NFS: Revert creation of IPv6 listeners for lockd and NFSv4 callbacks
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (6 preceding siblings ...)
  2009-03-12 16:07   ` [PATCH 07/40] SUNRPC: Remove @family argument from svc_create() and svc_create_pooled() Chuck Lever
@ 2009-03-12 16:07   ` Chuck Lever
  2009-03-12 16:08   ` [PATCH 09/40] SUNRPC: Set IPV6ONLY flag on PF_INET6 RPC listener sockets Chuck Lever
                     ` (5 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:07 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

We're about to convert over to using separate PF_INET and PF_INET6
listeners, instead of a single PF_INET6 listener that also receives
AF_INET requests and maps them to AF_INET6.

Clear the way by removing the logic in lockd and the NFSv4 callback
server that creates an AF_INET6 service listener.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/lockd/svc.c    |   13 +------------
 fs/nfs/callback.c |   14 ++------------
 2 files changed, 3 insertions(+), 24 deletions(-)

diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index d309200..566932b 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -53,17 +53,6 @@ static struct svc_rqst		*nlmsvc_rqst;
 unsigned long			nlmsvc_timeout;
 
 /*
- * If the kernel has IPv6 support available, always listen for
- * both AF_INET and AF_INET6 requests.
- */
-#if (defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)) && \
-	defined(CONFIG_SUNRPC_REGISTER_V4)
-static const sa_family_t	nlmsvc_family = AF_INET6;
-#else	/* (CONFIG_IPV6 || CONFIG_IPV6_MODULE) && CONFIG_SUNRPC_REGISTER_V4 */
-static const sa_family_t	nlmsvc_family = AF_INET;
-#endif	/* (CONFIG_IPV6 || CONFIG_IPV6_MODULE) && CONFIG_SUNRPC_REGISTER_V4 */
-
-/*
  * These can be set at insmod time (useful for NFS as root filesystem),
  * and also changed through the sysctl interface.  -- Jamie Lokier, Aug 2003
  */
@@ -211,7 +200,7 @@ static int create_lockd_listener(struct svc_serv *serv, char *name,
 
 	xprt = svc_find_xprt(serv, name, 0, 0);
 	if (xprt == NULL)
-		return svc_create_xprt(serv, name, nlmsvc_family,
+		return svc_create_xprt(serv, name, PF_INET,
 					port, SVC_SOCK_DEFAULTS);
 
 	svc_xprt_put(xprt);
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index ddf4b4a..0ef47df 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -41,16 +41,6 @@ unsigned short nfs_callback_tcpport;
 static const int nfs_set_port_min = 0;
 static const int nfs_set_port_max = 65535;
 
-/*
- * If the kernel has IPv6 support available, always listen for
- * both AF_INET and AF_INET6 requests.
- */
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-static const sa_family_t	nfs_callback_family = AF_INET6;
-#else
-static const sa_family_t	nfs_callback_family = AF_INET;
-#endif
-
 static int param_set_port(const char *val, struct kernel_param *kp)
 {
 	char *endp;
@@ -121,13 +111,13 @@ int nfs_callback_up(void)
 	if (!serv)
 		goto out_err;
 
-	ret = svc_create_xprt(serv, "tcp", nfs_callback_family,
+	ret = svc_create_xprt(serv, "tcp", PF_INET,
 				nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
 	if (ret <= 0)
 		goto out_err;
 	nfs_callback_tcpport = ret;
 	dprintk("NFS: Callback listener port = %u (af %u)\n",
-			nfs_callback_tcpport, nfs_callback_family);
+			nfs_callback_tcpport, PF_INET);
 
 	nfs_callback_info.rqst = svc_prepare_thread(serv, &serv->sv_pools[0]);
 	if (IS_ERR(nfs_callback_info.rqst)) {


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 09/40] SUNRPC: Set IPV6ONLY flag on PF_INET6 RPC listener sockets
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (7 preceding siblings ...)
  2009-03-12 16:07   ` [PATCH 08/40] NFS: Revert creation of IPv6 listeners for lockd and NFSv4 callbacks Chuck Lever
@ 2009-03-12 16:08   ` Chuck Lever
  2009-03-12 16:08   ` [PATCH 10/40] SUNRPC: Use IPv4 loopback for registering AF_INET6 kernel RPC services Chuck Lever
                     ` (4 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:08 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

We are about to convert to using separate RPC listener sockets for
PF_INET and PF_INET6.  This echoes the way IPv6 is handled in user
space by TI-RPC, and eliminates the need for ULPs to worry about
mapped IPv4 AF_INET6 addresses when doing address comparisons.

Start by setting the IPV6ONLY flag on PF_INET6 RPC listener sockets.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 net/sunrpc/svcsock.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index d00bc33..ac6cd65 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1144,13 +1144,11 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
 		svc_tcp_init(svsk, serv);
 
 	/*
-	 * We start one listener per sv_serv.  We want AF_INET
-	 * requests to be automatically shunted to our PF_INET6
-	 * listener using a mapped IPv4 address.  Make sure
-	 * no-one starts an equivalent IPv4 listener, which
-	 * would steal our incoming connections.
+	 * If this is a PF_INET6 listener, we want to avoid
+	 * getting requests from IPv4 remotes.  Those should
+	 * be shunted to a PF_INET listener via rpcbind.
 	 */
-	val = 0;
+	val = 1;
 	if (inet->sk_family == PF_INET6)
 		kernel_setsockopt(sock, SOL_IPV6, IPV6_V6ONLY,
 					(char *)&val, sizeof(val));


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 10/40] SUNRPC: Use IPv4 loopback for registering AF_INET6 kernel RPC services
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (8 preceding siblings ...)
  2009-03-12 16:08   ` [PATCH 09/40] SUNRPC: Set IPV6ONLY flag on PF_INET6 RPC listener sockets Chuck Lever
@ 2009-03-12 16:08   ` Chuck Lever
  2009-03-12 16:08   ` [PATCH 12/40] SUNRPC: Clean up address type casts in rpcb_v4_register() Chuck Lever
                     ` (3 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:08 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

The kernel uses an IPv6 loopback address when registering its AF_INET6
RPC services so that it can tell whether the local portmapper is
actually IPv6-enabled.

Since the legacy portmapper doesn't listen on IPv6, however, this
causes a long timeout on older systems if the kernel happens to try
creating and registering an AF_INET6 RPC service.  Originally I wanted
to use a connected transport (either TCP or connected UDP) so that the
upcall would fail immediately if the portmapper wasn't listening on
IPv6, but we never agreed on what transport to use.

In the end, it's of little consequence to the kernel whether the local
portmapper is listening on IPv6.  It's only important whether the
portmapper supports rpcbind v4.  And the kernel can't tell that at all
if it is sending requests via IPv6 -- the portmapper will just ignore
them.

So, send both rpcbind v2 and v4 SET/UNSET requests via IPv4 loopback
to maintain better backwards compatibility between new kernels and
legacy user space, and prevent multi-second hangs in some cases when
the kernel attempts to register RPC services.

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>
---

 net/sunrpc/rpcb_clnt.c |   23 ++++++-----------------
 1 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 03ae007..0e9150d 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -124,12 +124,6 @@ static const struct sockaddr_in rpcb_inaddr_loopback = {
 	.sin_port		= htons(RPCBIND_PORT),
 };
 
-static const struct sockaddr_in6 rpcb_in6addr_loopback = {
-	.sin6_family		= AF_INET6,
-	.sin6_addr		= IN6ADDR_LOOPBACK_INIT,
-	.sin6_port		= htons(RPCBIND_PORT),
-};
-
 static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr,
 					  size_t addrlen, u32 version)
 {
@@ -176,9 +170,10 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
 	return rpc_create(&args);
 }
 
-static int rpcb_register_call(struct sockaddr *addr, size_t addrlen,
-			      u32 version, struct rpc_message *msg)
+static int rpcb_register_call(u32 version, struct rpc_message *msg)
 {
+	struct sockaddr *addr = (struct sockaddr *)&rpcb_inaddr_loopback;
+	size_t addrlen = sizeof(rpcb_inaddr_loopback);
 	struct rpc_clnt *rpcb_clnt;
 	int result, error = 0;
 
@@ -254,9 +249,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
 	if (port)
 		msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
 
-	return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback,
-					sizeof(rpcb_inaddr_loopback),
-					RPCBVERS_2, &msg);
+	return rpcb_register_call(RPCBVERS_2, &msg);
 }
 
 /*
@@ -284,9 +277,7 @@ static int rpcb_register_netid4(struct sockaddr_in *address_to_register,
 	if (port)
 		msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
 
-	return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback,
-					sizeof(rpcb_inaddr_loopback),
-					RPCBVERS_4, msg);
+	return rpcb_register_call(RPCBVERS_4, msg);
 }
 
 /*
@@ -318,9 +309,7 @@ static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
 	if (port)
 		msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
 
-	return rpcb_register_call((struct sockaddr *)&rpcb_in6addr_loopback,
-					sizeof(rpcb_in6addr_loopback),
-					RPCBVERS_4, msg);
+	return rpcb_register_call(RPCBVERS_4, msg);
 }
 
 /**


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 12/40] SUNRPC: Clean up address type casts in rpcb_v4_register()
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (9 preceding siblings ...)
  2009-03-12 16:08   ` [PATCH 10/40] SUNRPC: Use IPv4 loopback for registering AF_INET6 kernel RPC services Chuck Lever
@ 2009-03-12 16:08   ` Chuck Lever
  2009-03-12 16:08   ` [PATCH 13/40] SUNRPC: rpcbind actually interprets r_owner string Chuck Lever
                     ` (2 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:08 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

Clean up: Simplify rpcb_v4_register() and its helpers by moving the
details of sockaddr type casting to rpcb_v4_register()'s helper
functions.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 net/sunrpc/rpcb_clnt.c |   26 ++++++++++++--------------
 1 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 0e9150d..317eb8a 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -170,7 +170,7 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
 	return rpc_create(&args);
 }
 
-static int rpcb_register_call(u32 version, struct rpc_message *msg)
+static int rpcb_register_call(const u32 version, struct rpc_message *msg)
 {
 	struct sockaddr *addr = (struct sockaddr *)&rpcb_inaddr_loopback;
 	size_t addrlen = sizeof(rpcb_inaddr_loopback);
@@ -255,17 +255,17 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
 /*
  * Fill in AF_INET family-specific arguments to register
  */
-static int rpcb_register_netid4(struct sockaddr_in *address_to_register,
+static int rpcb_register_netid4(const struct sockaddr *sap,
 				struct rpc_message *msg)
 {
+	const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
 	struct rpcbind_args *map = msg->rpc_argp;
-	unsigned short port = ntohs(address_to_register->sin_port);
+	unsigned short port = ntohs(sin->sin_port);
 	char buf[32];
 
 	/* Construct AF_INET universal address */
 	snprintf(buf, sizeof(buf), "%pI4.%u.%u",
-		 &address_to_register->sin_addr.s_addr,
-		 port >> 8, port & 0xff);
+		 &sin->sin_addr.s_addr, port >> 8, port & 0xff);
 	map->r_addr = buf;
 
 	dprintk("RPC:       %sregistering [%u, %u, %s, '%s'] with "
@@ -283,21 +283,21 @@ static int rpcb_register_netid4(struct sockaddr_in *address_to_register,
 /*
  * Fill in AF_INET6 family-specific arguments to register
  */
-static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
+static int rpcb_register_netid6(const struct sockaddr *sap,
 				struct rpc_message *msg)
 {
+	const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
 	struct rpcbind_args *map = msg->rpc_argp;
-	unsigned short port = ntohs(address_to_register->sin6_port);
+	unsigned short port = ntohs(sin6->sin6_port);
 	char buf[64];
 
 	/* Construct AF_INET6 universal address */
-	if (ipv6_addr_any(&address_to_register->sin6_addr))
+	if (ipv6_addr_any(&sin6->sin6_addr))
 		snprintf(buf, sizeof(buf), "::.%u.%u",
 				port >> 8, port & 0xff);
 	else
 		snprintf(buf, sizeof(buf), "%pI6.%u.%u",
-			 &address_to_register->sin6_addr,
-			 port >> 8, port & 0xff);
+			 &sin6->sin6_addr, port >> 8, port & 0xff);
 	map->r_addr = buf;
 
 	dprintk("RPC:       %sregistering [%u, %u, %s, '%s'] with "
@@ -369,11 +369,9 @@ int rpcb_v4_register(const u32 program, const u32 version,
 
 	switch (address->sa_family) {
 	case AF_INET:
-		return rpcb_register_netid4((struct sockaddr_in *)address,
-					    &msg);
+		return rpcb_register_netid4(address, &msg);
 	case AF_INET6:
-		return rpcb_register_netid6((struct sockaddr_in6 *)address,
-					    &msg);
+		return rpcb_register_netid6(address, &msg);
 	}
 
 	return -EAFNOSUPPORT;


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 13/40] SUNRPC: rpcbind actually interprets r_owner string
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (10 preceding siblings ...)
  2009-03-12 16:08   ` [PATCH 12/40] SUNRPC: Clean up address type casts in rpcb_v4_register() Chuck Lever
@ 2009-03-12 16:08   ` Chuck Lever
  2009-03-12 16:08   ` [PATCH 14/40] SUNRPC: Allow callers to pass rpcb_v4_register a NULL address Chuck Lever
  2009-03-12 16:08   ` [PATCH 15/40] SUNRPC: Simplify svc_unregister() Chuck Lever
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:08 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

RFC 1833 has little to say about the contents of r_owner; it only
specifies that it is a string, and states that it is used to control
who can UNSET an entry.

Our port of rpcbind (from Sun) assumes this string contains a numeric
UID value, not alphabetical or symbolic characters, but checks this
value only for AF_LOCAL RPCB_SET or RPCB_UNSET requests.  In all other
cases, rpcbind ignores the contents of the r_owner string.

The reference user space implementation of rpcb_set(3) uses a numeric
UID for all SET/UNSET requests (even via the network) and an empty
string for all other requests.  We emulate that behavior here to
maintain bug-for-bug compatibility.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 net/sunrpc/rpcb_clnt.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 317eb8a..4e86dfe 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -63,9 +63,16 @@ enum {
  * r_owner
  *
  * The "owner" is allowed to unset a service in the rpcbind database.
- * We always use the following (arbitrary) fixed string.
+ *
+ * For AF_LOCAL SET/UNSET requests, rpcbind treats this string as a
+ * UID which it maps to a local user name via a password lookup.
+ * In all other cases it is ignored.
+ *
+ * For SET/UNSET requests, user space provides a value, even for
+ * network requests, and GETADDR uses an empty string.  We follow
+ * those precedents here.
  */
-#define RPCB_OWNER_STRING	"rpcb"
+#define RPCB_OWNER_STRING	"0"
 #define RPCB_MAXOWNERLEN	sizeof(RPCB_OWNER_STRING)
 
 static void			rpcb_getport_done(struct rpc_task *, void *);
@@ -566,7 +573,7 @@ void rpcb_getport_async(struct rpc_task *task)
 	map->r_xprt = xprt_get(xprt);
 	map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
 	map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR);
-	map->r_owner = RPCB_OWNER_STRING;	/* ignored for GETADDR */
+	map->r_owner = "";
 	map->r_status = -EIO;
 
 	child = rpcb_call_async(rpcb_clnt, map, proc);


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 14/40] SUNRPC: Allow callers to pass rpcb_v4_register a NULL address
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (11 preceding siblings ...)
  2009-03-12 16:08   ` [PATCH 13/40] SUNRPC: rpcbind actually interprets r_owner string Chuck Lever
@ 2009-03-12 16:08   ` Chuck Lever
  2009-03-12 16:08   ` [PATCH 15/40] SUNRPC: Simplify svc_unregister() Chuck Lever
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:08 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

The user space TI-RPC library uses an empty string for the universal
address when unregistering all target addresses for [program, version].
The kernel's rpcb client should behave the same way.

Here, we are switching between several registration methods based on
the protocol family of the incoming address.  Rename the other rpcbind
v4 registration functions to make it clear that they, as well, are
switched on protocol family.  In /etc/netconfig, this is either "inet"
or "inet6".

NB: The loopback protocol families are not supported in the kernel.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 net/sunrpc/rpcb_clnt.c |   38 ++++++++++++++++++++++++++++----------
 1 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 4e86dfe..4a7a8ae 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -262,8 +262,8 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
 /*
  * Fill in AF_INET family-specific arguments to register
  */
-static int rpcb_register_netid4(const struct sockaddr *sap,
-				struct rpc_message *msg)
+static int rpcb_register_inet4(const struct sockaddr *sap,
+			       struct rpc_message *msg)
 {
 	const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
 	struct rpcbind_args *map = msg->rpc_argp;
@@ -290,8 +290,8 @@ static int rpcb_register_netid4(const struct sockaddr *sap,
 /*
  * Fill in AF_INET6 family-specific arguments to register
  */
-static int rpcb_register_netid6(const struct sockaddr *sap,
-				struct rpc_message *msg)
+static int rpcb_register_inet6(const struct sockaddr *sap,
+			       struct rpc_message *msg)
 {
 	const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
 	struct rpcbind_args *map = msg->rpc_argp;
@@ -319,6 +319,20 @@ static int rpcb_register_netid6(const struct sockaddr *sap,
 	return rpcb_register_call(RPCBVERS_4, msg);
 }
 
+static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
+{
+	struct rpcbind_args *map = msg->rpc_argp;
+
+	dprintk("RPC:       unregistering [%u, %u, '%s'] with "
+		"local rpcbind\n",
+			map->r_prog, map->r_vers, map->r_netid);
+
+	map->r_addr = "";
+	msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
+
+	return rpcb_register_call(RPCBVERS_4, msg);
+}
+
 /**
  * rpcb_v4_register - set or unset a port registration with the local rpcbind
  * @program: RPC program number of service to (un)register
@@ -336,10 +350,11 @@ static int rpcb_register_netid6(const struct sockaddr *sap,
  * invoke this function once for each [program, version, address,
  * netid] tuple they wish to advertise.
  *
- * Callers may also unregister RPC services that are no longer
- * available by setting the port number in the passed-in address
- * to zero.  Callers pass a netid of "" to unregister all
- * transport netids associated with [program, version, address].
+ * Callers may also unregister RPC services that are registered at a
+ * specific address by setting the port number in @address to zero.
+ * They may unregister all registered protocol families at once for
+ * a service by passing a NULL @address argument.  If @netid is ""
+ * then all netids for [program, version, address] are unregistered.
  *
  * This function uses rpcbind protocol version 4 to contact the
  * local rpcbind daemon.  The local rpcbind daemon must support
@@ -374,11 +389,14 @@ int rpcb_v4_register(const u32 program, const u32 version,
 		.rpc_argp	= &map,
 	};
 
+	if (address == NULL)
+		return rpcb_unregister_all_protofamilies(&msg);
+
 	switch (address->sa_family) {
 	case AF_INET:
-		return rpcb_register_netid4(address, &msg);
+		return rpcb_register_inet4(address, &msg);
 	case AF_INET6:
-		return rpcb_register_netid6(address, &msg);
+		return rpcb_register_inet6(address, &msg);
 	}
 
 	return -EAFNOSUPPORT;


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 15/40] SUNRPC: Simplify svc_unregister()
       [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (12 preceding siblings ...)
  2009-03-12 16:08   ` [PATCH 14/40] SUNRPC: Allow callers to pass rpcb_v4_register a NULL address Chuck Lever
@ 2009-03-12 16:08   ` Chuck Lever
  13 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2009-03-12 16:08 UTC (permalink / raw)
  To: bfields, trond.myklebust; +Cc: linux-nfs

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>
---

 net/sunrpc/svc.c |   35 ++++++++++++++---------------------
 1 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 17e0d72..bd0ee31 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,
 	return error;
 }
 
-#ifdef CONFIG_SUNRPC_REGISTER_V4
-
+/*
+ * If user space is running rpcbind, it should take the v4 UNSET
+ * and clear everything for this [program, version].  If user space
+ * is running portmap, it will reject the v4 UNSET, but won't have
+ * any "inet6" entries anyway.  So a PMAP_UNSET should be sufficient
+ * in this case to clear all existing entries for [program, version].
+ */
 static void __svc_unregister(const u32 program, const u32 version,
 			     const char *progname)
 {
-	struct sockaddr_in6 sin6 = {
-		.sin6_family		= AF_INET6,
-		.sin6_addr		= IN6ADDR_ANY_INIT,
-		.sin6_port		= 0,
-	};
 	int error;
 
-	error = rpcb_v4_register(program, version,
-				(struct sockaddr *)&sin6, "");
-	dprintk("svc: %s(%sv%u), error %d\n",
-			__func__, progname, version, error);
-}
-
-#else	/* CONFIG_SUNRPC_REGISTER_V4 */
+	error = rpcb_v4_register(program, version, NULL, "");
 
-static void __svc_unregister(const u32 program, const u32 version,
-			     const char *progname)
-{
-	int error;
+	/*
+	 * User space didn't support rpcbind v4, so retry this
+	 * request with the legacy rpcbind v2 protocol.
+	 */
+	if (error == -EPROTONOSUPPORT)
+		error = rpcb_register(program, version, 0, 0);
 
-	error = rpcb_register(program, version, 0, 0);
 	dprintk("svc: %s(%sv%u), error %d\n",
 			__func__, progname, version, error);
 }
 
-#endif	/* CONFIG_SUNRPC_REGISTER_V4 */
-
 /*
  * All netids, bind addresses and ports registered for [program, version]
  * are removed from the local rpcbind database (if the service is not


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 01/40] SUNRPC: Fix return type of svc_addr_len()
       [not found]     ` <20090312160706.16019.81338.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2009-03-18 22:08       ` J. Bruce Fields
  2009-03-18 22:40         ` Chuck Lever
  0 siblings, 1 reply; 21+ messages in thread
From: J. Bruce Fields @ 2009-03-18 22:08 UTC (permalink / raw)
  To: Chuck Lever; +Cc: trond.myklebust, linux-nfs, Tom Tucker

On Thu, Mar 12, 2009 at 12:07:06PM -0400, Chuck Lever wrote:
> The svc_addr_len() helper function can return a negative errno value,
> but its return type is size_t, which is unsigned.
> 
> The RDMA transport code passes this return value directly to memset(),
> without checking first if it's negative.  This could cause memset() to
> clobber a large piece of memory if svc_addr_len() has returned an
> error.

Is this something that can in fact happen, and if so, in what
circumstances?  And what ends up happening to the -EAFNOSUPPORT error?

Tracing up through the callers, I get lost somewhere in the ib code.
Maybe Tom can rescue me....

--b.

> 
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
> 
>  include/linux/sunrpc/svc_xprt.h          |    3 ++-
>  net/sunrpc/xprtrdma/svc_rdma_transport.c |   16 ++++++++++++++--
>  2 files changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
> index 0127dac..c2aa8cd 100644
> --- a/include/linux/sunrpc/svc_xprt.h
> +++ b/include/linux/sunrpc/svc_xprt.h
> @@ -113,7 +113,7 @@ static inline unsigned short svc_addr_port(struct sockaddr *sa)
>  	return ret;
>  }
>  
> -static inline size_t svc_addr_len(struct sockaddr *sa)
> +static inline int svc_addr_len(const struct sockaddr *sa)
>  {
>  	switch (sa->sa_family) {
>  	case AF_INET:
> @@ -121,6 +121,7 @@ static inline size_t svc_addr_len(struct sockaddr *sa)
>  	case AF_INET6:
>  		return sizeof(struct sockaddr_in6);
>  	}
> +
>  	return -EAFNOSUPPORT;
>  }
>  
> diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
> index 3d810e7..d1ec6f9 100644
> --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
> +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
> @@ -546,6 +546,7 @@ static void handle_connect_req(struct rdma_cm_id *new_cma_id, size_t client_ird)
>  	struct svcxprt_rdma *listen_xprt = new_cma_id->context;
>  	struct svcxprt_rdma *newxprt;
>  	struct sockaddr *sa;
> +	int len;
>  
>  	/* Create a new transport */
>  	newxprt = rdma_create_xprt(listen_xprt->sc_xprt.xpt_server, 0);
> @@ -563,9 +564,20 @@ static void handle_connect_req(struct rdma_cm_id *new_cma_id, size_t client_ird)
>  
>  	/* Set the local and remote addresses in the transport */
>  	sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.dst_addr;
> -	svc_xprt_set_remote(&newxprt->sc_xprt, sa, svc_addr_len(sa));
> +	len = svc_addr_len(sa);
> +	if (len < 0) {
> +		dprintk("svcrdma: dst_addr has a bad address family\n");
> +		return;
> +	}
> +	svc_xprt_set_remote(&newxprt->sc_xprt, sa, len);
> +
>  	sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.src_addr;
> -	svc_xprt_set_local(&newxprt->sc_xprt, sa, svc_addr_len(sa));
> +	len = svc_addr_len(sa);
> +	if (len < 0) {
> +		dprintk("svcrdma: src_addr has a bad address family\n");
> +		return;
> +	}
> +	svc_xprt_set_local(&newxprt->sc_xprt, sa, len);
>  
>  	/*
>  	 * Enqueue the new transport on the accept queue of the listening
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 02/40] SUNRPC: Clean up static inline functions in svc_xprt.h
       [not found]     ` <20090312160713.16019.56290.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2009-03-18 22:13       ` J. Bruce Fields
  0 siblings, 0 replies; 21+ messages in thread
From: J. Bruce Fields @ 2009-03-18 22:13 UTC (permalink / raw)
  To: Chuck Lever; +Cc: trond.myklebust, linux-nfs

On Thu, Mar 12, 2009 at 12:07:14PM -0400, Chuck Lever wrote:
> Clean up:  Enable the use of const arguments in higher level svc_ APIs
> by adding const to the arguments of the helper functions in svc_xprt.h

OK--applied.--b.

> 
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
> 
>  include/linux/sunrpc/svc_xprt.h |   46 ++++++++++++++++++++++-----------------
>  1 files changed, 26 insertions(+), 20 deletions(-)
> 
> diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
> index c2aa8cd..ee21e8a 100644
> --- a/include/linux/sunrpc/svc_xprt.h
> +++ b/include/linux/sunrpc/svc_xprt.h
> @@ -88,29 +88,32 @@ static inline void svc_xprt_get(struct svc_xprt *xprt)
>  	kref_get(&xprt->xpt_ref);
>  }
>  static inline void svc_xprt_set_local(struct svc_xprt *xprt,
> -				      struct sockaddr *sa, int salen)
> +				      const struct sockaddr *sa,
> +				      const size_t salen)
>  {
>  	memcpy(&xprt->xpt_local, sa, salen);
>  	xprt->xpt_locallen = salen;
>  }
>  static inline void svc_xprt_set_remote(struct svc_xprt *xprt,
> -				       struct sockaddr *sa, int salen)
> +				       const struct sockaddr *sa,
> +				       const size_t salen)
>  {
>  	memcpy(&xprt->xpt_remote, sa, salen);
>  	xprt->xpt_remotelen = salen;
>  }
> -static inline unsigned short svc_addr_port(struct sockaddr *sa)
> +static inline unsigned short svc_addr_port(const struct sockaddr *sa)
>  {
> -	unsigned short ret = 0;
> +	const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
> +	const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
> +
>  	switch (sa->sa_family) {
>  	case AF_INET:
> -		ret = ntohs(((struct sockaddr_in *)sa)->sin_port);
> -		break;
> +		return ntohs(sin->sin_port);
>  	case AF_INET6:
> -		ret = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
> -		break;
> +		return ntohs(sin6->sin6_port);
>  	}
> -	return ret;
> +
> +	return 0;
>  }
>  
>  static inline int svc_addr_len(const struct sockaddr *sa)
> @@ -125,36 +128,39 @@ static inline int svc_addr_len(const struct sockaddr *sa)
>  	return -EAFNOSUPPORT;
>  }
>  
> -static inline unsigned short svc_xprt_local_port(struct svc_xprt *xprt)
> +static inline unsigned short svc_xprt_local_port(const struct svc_xprt *xprt)
>  {
> -	return svc_addr_port((struct sockaddr *)&xprt->xpt_local);
> +	return svc_addr_port((const struct sockaddr *)&xprt->xpt_local);
>  }
>  
> -static inline unsigned short svc_xprt_remote_port(struct svc_xprt *xprt)
> +static inline unsigned short svc_xprt_remote_port(const struct svc_xprt *xprt)
>  {
> -	return svc_addr_port((struct sockaddr *)&xprt->xpt_remote);
> +	return svc_addr_port((const struct sockaddr *)&xprt->xpt_remote);
>  }
>  
> -static inline char *__svc_print_addr(struct sockaddr *addr,
> -				     char *buf, size_t len)
> +static inline char *__svc_print_addr(const struct sockaddr *addr,
> +				     char *buf, const size_t len)
>  {
> +	const struct sockaddr_in *sin = (const struct sockaddr_in *)addr;
> +	const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)addr;
> +
>  	switch (addr->sa_family) {
>  	case AF_INET:
> -		snprintf(buf, len, "%pI4, port=%u",
> -			&((struct sockaddr_in *)addr)->sin_addr,
> -			ntohs(((struct sockaddr_in *) addr)->sin_port));
> +		snprintf(buf, len, "%pI4, port=%u", &sin->sin_addr,
> +			ntohs(sin->sin_port));
>  		break;
>  
>  	case AF_INET6:
>  		snprintf(buf, len, "%pI6, port=%u",
> -			 &((struct sockaddr_in6 *)addr)->sin6_addr,
> -			ntohs(((struct sockaddr_in6 *) addr)->sin6_port));
> +			 &sin6->sin6_addr,
> +			ntohs(sin6->sin6_port));
>  		break;
>  
>  	default:
>  		snprintf(buf, len, "unknown address type: %d", addr->sa_family);
>  		break;
>  	}
> +
>  	return buf;
>  }
>  #endif /* SUNRPC_SVC_XPRT_H */
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 03/40] SUNRPC: Clean up svc_find_xprt() calling sequence
       [not found]     ` <20090312160721.16019.89653.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2009-03-18 22:34       ` J. Bruce Fields
  2009-03-18 22:55       ` J. Bruce Fields
  1 sibling, 0 replies; 21+ messages in thread
From: J. Bruce Fields @ 2009-03-18 22:34 UTC (permalink / raw)
  To: Chuck Lever; +Cc: trond.myklebust, linux-nfs

On Thu, Mar 12, 2009 at 12:07:21PM -0400, Chuck Lever wrote:
> Clean up: add documentating comment and use appropriate data types for
> svc_find_xprt()'s arguments.
> 
> This also eliminates a mixed sign comparison: @port was an int, while
> the return value of svc_xprt_local_port() is an unsigned short.

OK.  Applied, though:

> @@ -1042,14 +1048,14 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt)
>   * wild-card, and will result in matching the first transport in the
>   * service's list that has a matching class name.
>   */
> -struct svc_xprt *svc_find_xprt(struct svc_serv *serv, char *xcl_name,
> -			       int af, int port)
> +struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
> +			       const sa_family_t af, const unsigned short port)
>  {
>  	struct svc_xprt *xprt;
>  	struct svc_xprt *found = NULL;
>  
>  	/* Sanity check the args */
> -	if (!serv || !xcl_name)
> +	if (serv == NULL || xcl_name == NULL)
>  		return found;

Maybe that's better, maybe not, I don't know, but: let's make allowances
for *some* variation in individual style.

Applying as-is, but in future, I'd rather that level of decision be left
to the preferences of whoever wrote the code.

--b.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 01/40] SUNRPC: Fix return type of svc_addr_len()
  2009-03-18 22:08       ` J. Bruce Fields
@ 2009-03-18 22:40         ` Chuck Lever
  0 siblings, 0 replies; 21+ messages in thread
From: Chuck Lever @ 2009-03-18 22:40 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: trond.myklebust, linux-nfs, Tom Tucker

On Mar 18, 2009, at Mar 18, 2009, 6:08 PM, J. Bruce Fields wrote:
> On Thu, Mar 12, 2009 at 12:07:06PM -0400, Chuck Lever wrote:
>> The svc_addr_len() helper function can return a negative errno value,
>> but its return type is size_t, which is unsigned.
>>
>> The RDMA transport code passes this return value directly to  
>> memset(),
>> without checking first if it's negative.  This could cause memset()  
>> to
>> clobber a large piece of memory if svc_addr_len() has returned an
>> error.
>
> Is this something that can in fact happen, and if so, in what
> circumstances?

If @sa contains an address whose family is not recognized by  
svc_addr_len(), it will return -EAFNOSUPPORT.  That's mostly likely to  
occur because of a programming error, but we still want to minimize  
the risk of memory or data corruption.

> And what ends up happening to the -EAFNOSUPPORT error?

I think, since the caller returns void, that call turns into a no-op,  
and no connection is made.  But Tom should verify.

> Tracing up through the callers, I get lost somewhere in the ib code.
> Maybe Tom can rescue me....
>
> --b.
>
>>
>> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
>> ---
>>
>> include/linux/sunrpc/svc_xprt.h          |    3 ++-
>> net/sunrpc/xprtrdma/svc_rdma_transport.c |   16 ++++++++++++++--
>> 2 files changed, 16 insertions(+), 3 deletions(-)
>>
>> diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/ 
>> svc_xprt.h
>> index 0127dac..c2aa8cd 100644
>> --- a/include/linux/sunrpc/svc_xprt.h
>> +++ b/include/linux/sunrpc/svc_xprt.h
>> @@ -113,7 +113,7 @@ static inline unsigned short  
>> svc_addr_port(struct sockaddr *sa)
>> 	return ret;
>> }
>>
>> -static inline size_t svc_addr_len(struct sockaddr *sa)
>> +static inline int svc_addr_len(const struct sockaddr *sa)
>> {
>> 	switch (sa->sa_family) {
>> 	case AF_INET:
>> @@ -121,6 +121,7 @@ static inline size_t svc_addr_len(struct  
>> sockaddr *sa)
>> 	case AF_INET6:
>> 		return sizeof(struct sockaddr_in6);
>> 	}
>> +
>> 	return -EAFNOSUPPORT;
>> }
>>
>> diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/ 
>> xprtrdma/svc_rdma_transport.c
>> index 3d810e7..d1ec6f9 100644
>> --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
>> +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
>> @@ -546,6 +546,7 @@ static void handle_connect_req(struct  
>> rdma_cm_id *new_cma_id, size_t client_ird)
>> 	struct svcxprt_rdma *listen_xprt = new_cma_id->context;
>> 	struct svcxprt_rdma *newxprt;
>> 	struct sockaddr *sa;
>> +	int len;
>>
>> 	/* Create a new transport */
>> 	newxprt = rdma_create_xprt(listen_xprt->sc_xprt.xpt_server, 0);
>> @@ -563,9 +564,20 @@ static void handle_connect_req(struct  
>> rdma_cm_id *new_cma_id, size_t client_ird)
>>
>> 	/* Set the local and remote addresses in the transport */
>> 	sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.dst_addr;
>> -	svc_xprt_set_remote(&newxprt->sc_xprt, sa, svc_addr_len(sa));
>> +	len = svc_addr_len(sa);
>> +	if (len < 0) {
>> +		dprintk("svcrdma: dst_addr has a bad address family\n");
>> +		return;
>> +	}
>> +	svc_xprt_set_remote(&newxprt->sc_xprt, sa, len);
>> +
>> 	sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.src_addr;
>> -	svc_xprt_set_local(&newxprt->sc_xprt, sa, svc_addr_len(sa));
>> +	len = svc_addr_len(sa);
>> +	if (len < 0) {
>> +		dprintk("svcrdma: src_addr has a bad address family\n");
>> +		return;
>> +	}
>> +	svc_xprt_set_local(&newxprt->sc_xprt, sa, len);
>>
>> 	/*
>> 	 * Enqueue the new transport on the accept queue of the listening
>>

-- 
Chuck Lever
chuck[dot]lever[at]oracle[dot]com





^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 03/40] SUNRPC: Clean up svc_find_xprt() calling sequence
       [not found]     ` <20090312160721.16019.89653.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2009-03-18 22:34       ` J. Bruce Fields
@ 2009-03-18 22:55       ` J. Bruce Fields
  1 sibling, 0 replies; 21+ messages in thread
From: J. Bruce Fields @ 2009-03-18 22:55 UTC (permalink / raw)
  To: Chuck Lever; +Cc: trond.myklebust, linux-nfs

On Thu, Mar 12, 2009 at 12:07:21PM -0400, Chuck Lever wrote:
> Clean up: add documentating comment and use appropriate data types for
> svc_find_xprt()'s arguments.
> 
> This also eliminates a mixed sign comparison: @port was an int, while
> the return value of svc_xprt_local_port() is an unsigned short.

Actually, I had second thoughts: the caller is in fact passing in an
int, obtained from sscanf.  Converting to a short introduces some
aliasing that could cause the comparison to succeed in some cases when
it didn't used to, hence catching fewer user errors, right?

So, dropping this one for now.

--b.

> 
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
> 
>  include/linux/sunrpc/svc_xprt.h |    3 ++-
>  net/sunrpc/svc_xprt.c           |   16 +++++++++++-----
>  2 files changed, 13 insertions(+), 6 deletions(-)
> 
> diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
> index ee21e8a..167e4b5 100644
> --- a/include/linux/sunrpc/svc_xprt.h
> +++ b/include/linux/sunrpc/svc_xprt.h
> @@ -80,7 +80,8 @@ void	svc_close_xprt(struct svc_xprt *xprt);
>  void	svc_delete_xprt(struct svc_xprt *xprt);
>  int	svc_port_is_privileged(struct sockaddr *sin);
>  int	svc_print_xprts(char *buf, int maxlen);
> -struct	svc_xprt *svc_find_xprt(struct svc_serv *, char *, int, int);
> +struct	svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
> +			const sa_family_t af, const unsigned short port);
>  int	svc_xprt_names(struct svc_serv *serv, char *buf, int buflen);
>  
>  static inline void svc_xprt_get(struct svc_xprt *xprt)
> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
> index e588df5..c947c93 100644
> --- a/net/sunrpc/svc_xprt.c
> +++ b/net/sunrpc/svc_xprt.c
> @@ -1033,7 +1033,13 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt)
>  	return dr;
>  }
>  
> -/*
> +/**
> + * svc_find_xprt - find an RPC transport instance
> + * @serv: pointer to svc_serv to search
> + * @xcl_name: C string containing transport's class name
> + * @af: Address family of transport's local address
> + * @port: transport's IP port number
> + *
>   * Return the transport instance pointer for the endpoint accepting
>   * connections/peer traffic from the specified transport class,
>   * address family and port.
> @@ -1042,14 +1048,14 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt)
>   * wild-card, and will result in matching the first transport in the
>   * service's list that has a matching class name.
>   */
> -struct svc_xprt *svc_find_xprt(struct svc_serv *serv, char *xcl_name,
> -			       int af, int port)
> +struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
> +			       const sa_family_t af, const unsigned short port)
>  {
>  	struct svc_xprt *xprt;
>  	struct svc_xprt *found = NULL;
>  
>  	/* Sanity check the args */
> -	if (!serv || !xcl_name)
> +	if (serv == NULL || xcl_name == NULL)
>  		return found;
>  
>  	spin_lock_bh(&serv->sv_lock);
> @@ -1058,7 +1064,7 @@ struct svc_xprt *svc_find_xprt(struct svc_serv *serv, char *xcl_name,
>  			continue;
>  		if (af != AF_UNSPEC && af != xprt->xpt_local.ss_family)
>  			continue;
> -		if (port && port != svc_xprt_local_port(xprt))
> +		if (port != 0 && port != svc_xprt_local_port(xprt))
>  			continue;
>  		found = xprt;
>  		svc_xprt_get(xprt);
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 36/40] NFSD: Prevent buffer overflow in write_threads()
       [not found]   ` <20090312161129.16019.26502.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2009-03-18 23:54     ` J. Bruce Fields
  0 siblings, 0 replies; 21+ messages in thread
From: J. Bruce Fields @ 2009-03-18 23:54 UTC (permalink / raw)
  To: Chuck Lever; +Cc: trond.myklebust, linux-nfs

On Thu, Mar 12, 2009 at 12:11:30PM -0400, Chuck Lever wrote:
> Fix up write_threads() to eliminate the small possibility of
> overflowing its output buffer.

A gripe: could you be more specific about that "small possibility"?

Looks like the answer in this case is that the buffer overflow is
currently impossible, and that this is defensive programming against
someone making SIMPLE_TRANSACTION_LIMIT ridiculously small, or
something.  OK, but that should be stated very clearly in the commit
message.

(A lot of people may read a patch that begins "Prevent buffer overflow".
Let's be kind to them!  (A less alarming subject might also not be a bad
idea.))

Ditto for some of the other patches.

--b.

> 
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
> 
>  fs/nfsd/nfsctl.c |    9 +++++----
>  1 files changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
> index ce54d72..e8009c8 100644
> --- a/fs/nfsd/nfsctl.c
> +++ b/fs/nfsd/nfsctl.c
> @@ -666,9 +666,9 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
>  static ssize_t write_threads(struct file *file, char *buf, size_t size)
>  {
>  	char *mesg = buf;
> -	int rv;
> +
>  	if (size > 0) {
> -		int newthreads;
> +		int rv, newthreads;
>  		rv = get_int(&mesg, &newthreads);
>  		if (rv)
>  			return rv;
> @@ -678,8 +678,9 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
>  		if (rv)
>  			return rv;
>  	}
> -	sprintf(buf, "%d\n", nfsd_nrthreads());
> -	return strlen(buf);
> +
> +	return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n",
> +							nfsd_nrthreads());
>  }
>  
>  /**
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2009-03-18 23:55 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-12 16:06 [PATCH 00/40] Proposed patches for 2.6.30 Chuck Lever
     [not found] ` <20090312155609.16019.86499.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-12 16:07   ` [PATCH 01/40] SUNRPC: Fix return type of svc_addr_len() Chuck Lever
     [not found]     ` <20090312160706.16019.81338.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-18 22:08       ` J. Bruce Fields
2009-03-18 22:40         ` Chuck Lever
2009-03-12 16:07   ` [PATCH 02/40] SUNRPC: Clean up static inline functions in svc_xprt.h Chuck Lever
     [not found]     ` <20090312160713.16019.56290.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-18 22:13       ` J. Bruce Fields
2009-03-12 16:07   ` [PATCH 03/40] SUNRPC: Clean up svc_find_xprt() calling sequence Chuck Lever
     [not found]     ` <20090312160721.16019.89653.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-18 22:34       ` J. Bruce Fields
2009-03-18 22:55       ` J. Bruce Fields
2009-03-12 16:07   ` [PATCH 04/40] SUNRPC: Pass a family argument to svc_register() Chuck Lever
2009-03-12 16:07   ` [PATCH 05/40] SUNRPC: svc_setup_socket() gets protocol family from socket Chuck Lever
2009-03-12 16:07   ` [PATCH 06/40] SUNRPC: Change svc_create_xprt() to take a @family argument Chuck Lever
2009-03-12 16:07   ` [PATCH 07/40] SUNRPC: Remove @family argument from svc_create() and svc_create_pooled() Chuck Lever
2009-03-12 16:07   ` [PATCH 08/40] NFS: Revert creation of IPv6 listeners for lockd and NFSv4 callbacks Chuck Lever
2009-03-12 16:08   ` [PATCH 09/40] SUNRPC: Set IPV6ONLY flag on PF_INET6 RPC listener sockets Chuck Lever
2009-03-12 16:08   ` [PATCH 10/40] SUNRPC: Use IPv4 loopback for registering AF_INET6 kernel RPC services Chuck Lever
2009-03-12 16:08   ` [PATCH 12/40] SUNRPC: Clean up address type casts in rpcb_v4_register() Chuck Lever
2009-03-12 16:08   ` [PATCH 13/40] SUNRPC: rpcbind actually interprets r_owner string Chuck Lever
2009-03-12 16:08   ` [PATCH 14/40] SUNRPC: Allow callers to pass rpcb_v4_register a NULL address Chuck Lever
2009-03-12 16:08   ` [PATCH 15/40] SUNRPC: Simplify svc_unregister() Chuck Lever
     [not found] ` <20090312161129.16019.26502.stgit@ingres.1015granger.net>
     [not found]   ` <20090312161129.16019.26502.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-18 23:54     ` [PATCH 36/40] NFSD: Prevent buffer overflow in write_threads() J. Bruce Fields

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox