Repost of remaining server-side IPv6 patches
Subsystems (3)
cover Repost of remaining server-side IPv6 patches
Hi Bruce-
Repost of last week's IPv6 patch set. I've attempted to address your comments.
---
Aime Le Rouzic (1):
NFSD: Support AF_INET6 in svc_addsock() function
Chuck Lever (4):
NFSD: Create PF_INET6 listener in write_ports
SUNRPC: NFS kernel APIs shouldn't return ENOENT for "transport not found"
SUNRPC: Bury "#ifdef IPV6" in svc_create_xprt()
SUNRPC: Use rpc_pton() in ip_map_parse()
fs/lockd/svc.c | 2 -- fs/nfs/callback.c | 2 -- fs/nfsd/nfsctl.c | 24 ++++++++++++++++++----- net/sunrpc/svc_xprt.c | 9 ++++++++- net/sunrpc/svcauth_unix.c | 47 +++++++++++++++++++++++++-------------------- net/sunrpc/svcsock.c | 2 +- 6 files changed, 54 insertions(+), 32 deletions(-)
Signature · 1 line
Chuck Lever <[email protected]>
A message that is not in the archive (sent off-list or not yet received): 20100126190214.3368.89388.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]
PATCH 1/5 SUNRPC: Use rpc_pton() in ip_map_parse()
The existing logic in ip_map_parse() can not currently parse shorthanded IPv6 addresses (anything with a double colon), nor can it parse an IPv6 presentation address with a scope ID. An IPv6-enabled mountd can pass down both.
---
net/sunrpc/svcauth_unix.c | 47 +++++++++++++++++++++++++-------------------- 1 files changed, 26 insertions(+), 21 deletions(-)
net/sunrpc/svcauth_unix.c +26 -21
@@ -15,6 +15,7 @@#include <linux/kernel.h> #define RPCDBG_FACILITY RPCDBG_AUTH +#include <linux/sunrpc/clnt.h> /* * AUTHUNIX and AUTHNULL credentials are both handled here.
@@ -187,10 +188,13 @@ static int ip_map_parse(struct cache_detail *cd,* for scratch: */ char *buf = mesg;int len; -int b1, b2, b3, b4, b5, b6, b7, b8; -char c;char class[8 ]; -struct in6_addr addr; +union { +struct sockaddr sa; +struct sockaddr_in s4; +struct sockaddr_in6 s6; + } address; +struct sockaddr_in6 sin6;int err;struct ip_map *ipmp;
@@ -209,24 +213,24 @@ static int ip_map_parse(struct cache_detail *cd, len =qword_get (&mesg, buf, mlen);if (len <=0 )return -EINVAL ; -if (sscanf (buf,"%u.%u.%u.%u%c" , &b1, &b2, &b3, &b4, &c) ==4 ) { - addr.s6_addr32[0 ] =0 ; - addr.s6_addr32[1 ] =0 ; - addr.s6_addr32[2 ] =htonl (0xffff ); - addr.s6_addr32[3 ] = -htonl ((((((b1<<8 )|b2)<<8 )|b3)<<8 )|b4); - }else if (sscanf (buf,"%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x%c" , - &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) ==8 ) { - addr.s6_addr16[0 ] =htons (b1); - addr.s6_addr16[1 ] =htons (b2); - addr.s6_addr16[2 ] =htons (b3); - addr.s6_addr16[3 ] =htons (b4); - addr.s6_addr16[4 ] =htons (b5); - addr.s6_addr16[5 ] =htons (b6); - addr.s6_addr16[6 ] =htons (b7); - addr.s6_addr16[7 ] =htons (b8); - }else +if (rpc_pton (buf, len, &address.sa,sizeof (address)) ==0 )return -EINVAL ; +switch (address.sa.sa_family) { +case AF_INET : +/* Form a mapped IPv4 address in sin6 */ +memset (&sin6,0 ,sizeof (sin6)); + sin6.sin6_family =AF_INET6 ; + sin6.sin6_addr.s6_addr32[2 ] =htonl (0xffff ); + sin6.sin6_addr.s6_addr32[3 ] = address.s4.sin_addr.s_addr; +break ; +#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE ) +case AF_INET6 : +memcpy (&sin6, &address.s6,sizeof (sin6)); +break ; +#endif +default : +return -EINVAL ; + } expiry =get_expiry (&mesg);if (expiry ==0 )
@@ -243,7 +247,8 @@ static int ip_map_parse(struct cache_detail *cd, }else dom =NULL ; - ipmp =ip_map_lookup (class, &addr); +/* IPv6 scope IDs are ignored for now */ + ipmp =ip_map_lookup (class, &sin6.sin6_addr);if (ipmp) { err = ip_map_update(ipmp, container_of(dom, struct unix_domain, h),
PATCH 2/5 NFSD: Support AF_INET6 in svc_addsock() function
In reply to a message not in the archiveFrom: Aime Le Rouzic <[email protected]>
Relax the address family check at the top of svc_addsock() to allow AF_INET6 listener sockets to be specified via /proc/fs/nfsd/portlist.
---
net/sunrpc/svcsock.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
net/sunrpc/svcsock.c +1 -1
@@ -1357,7 +1357,7 @@ int svc_addsock(struct svc_serv *serv, const int fd, char *name_return,if (!so)return err; -if (so->sk->sk_family !=AF_INET ) +if ((so->sk->sk_family !=PF_INET ) && (so->sk->sk_family !=PF_INET6 )) err = -EAFNOSUPPORT ;else if (so->sk->sk_protocol !=IPPROTO_TCP && so->sk->sk_protocol !=IPPROTO_UDP )
PATCH 3/5 SUNRPC: Bury "#ifdef IPV6" in svc_create_xprt()
In reply to a message not in the archiveClean up: Bruce observed we have more or less common logic in each of svc_create_xprt()'s callers: the check to create an IPv6 RPC listener socket only if CONFIG_IPV6 is set. I'm about to add another case that does just the same.
If we move the ifdefs into __svc_xpo_create(), then svc_create_xprt() call sites can get rid of the "#ifdef" ugliness, and can use the same logic with or without IPv6 support available in the kernel.
---
fs/lockd/svc.c | 2 -- fs/nfs/callback.c | 2 -- net/sunrpc/svc_xprt.c | 4 ++++ 3 files changed, 4 insertions(+), 4 deletions(-)
fs/lockd/svc.c +0 -2
@@ -243,11 +243,9 @@ static int make_socks(struct svc_serv *serv)if (err <0 ) goto out_err; -#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE ) err =create_lockd_family (serv,PF_INET6 );if (err <0 && err != -EAFNOSUPPORT ) goto out_err; -#endif /* CONFIG_IPV6 || CONFIG_IPV6_MODULE */ warned =0 ;return 0 ;
fs/nfs/callback.c +0 -2
@@ -118,7 +118,6 @@ nfs4_callback_up(struct svc_serv *serv)dprintk ("NFS: Callback listener port = %u (af %u)\n" , nfs_callback_tcpport,PF_INET ); -#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE ) ret =svc_create_xprt (serv,"tcp" ,PF_INET6 , nfs_callback_set_tcpport,SVC_SOCK_ANONYMOUS );if (ret >0 ) {
@@ -129,7 +128,6 @@ nfs4_callback_up(struct svc_serv *serv) ret =0 ; else goto out_err; -#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ return svc_prepare_thread (serv, &serv->sv_pools[0 ]);
net/sunrpc/svc_xprt.c +4 -0
@@ -173,11 +173,13 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl, .sin_addr.s_addr = htonl(INADDR_ANY), .sin_port = htons(port), }; +#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE )struct sockaddr_in6 sin6 = { .sin6_family =AF_INET6 , .sin6_addr =IN6ADDR_ANY_INIT , .sin6_port =htons (port), }; +#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ struct sockaddr *sap;size_t len;
@@ -186,10 +188,12 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl, sap = (struct sockaddr *)&sin; len =sizeof (sin);break ; +#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE )case PF_INET6 : sap = (struct sockaddr *)&sin6; len =sizeof (sin6);break ; +#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ default :return ERR_PTR (-EAFNOSUPPORT ); }
PATCH 4/5 SUNRPC: NFS kernel APIs shouldn't return ENOENT for "transport not found"
In reply to a message not in the archivewrite_ports() converts svc_create_xprt()'s ENOENT error return to EPROTONOSUPPORT so that rpc.nfsd (in user space) can report an error message that makes sense.
It turns out that several of the other kernel APIs rpc.nfsd use can also return ENOENT from svc_create_xprt(), by way of lockd_up().
On the client side, an NFSv2 or NFSv3 mount request can also return the result of lockd_up(). This error may also be returned during an NFSv4 mount request, since the NFSv4 callback service uses svc_create_xprt() to create the callback listener. An ENOENT error return results in a confusing error message from the mount command.
Let's have svc_create_xprt() return EPROTONOSUPPORT instead of ENOENT.
---
fs/nfsd/nfsctl.c | 6 +----- net/sunrpc/svc_xprt.c | 5 ++++- 2 files changed, 5 insertions(+), 6 deletions(-)
fs/nfsd/nfsctl.c +1 -5
@@ -1002,12 +1002,8 @@ static ssize_t __write_ports_addxprt(char *buf) err =svc_create_xprt (nfsd_serv, transport,PF_INET , port,SVC_SOCK_ANONYMOUS ); -if (err <0 ) { -/* Give a reasonable perror msg for bad transport string */ -if (err == -ENOENT ) - err = -EPROTONOSUPPORT ; +if (err <0 )return err; - }return 0 ; }
net/sunrpc/svc_xprt.c +4 -1
@@ -235,7 +235,10 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, err:spin_unlock (&svc_xprt_class_lock);dprintk ("svc: transport %s not found\n" , xprt_name); -return -ENOENT ; + +/* This errno is exposed to user space. Provide a reasonable +* perror msg for a bad transport. */ +return -EPROTONOSUPPORT ; }EXPORT_SYMBOL_GPL (svc_create_xprt);
PATCH 5/5 NFSD: Create PF_INET6 listener in write_ports
In reply to a message not in the archiveTry to create a PF_INET6 listener for NFSD, if IPv6 is enabled in the kernel.
Make sure nfsd_serv's reference count is decreased if __write_ports_addxprt() failed to create a listener. See __write_ports_addfd().
Our current plan is to rely on rpc.nfsd to create appropriate IPv6 listeners when server-side NFS/IPv6 support is desired. Legacy behavior, via the write_threads or write_svc kernel APIs, will remain the same -- only IPv4 listeners are created.
---
fs/nfsd/nfsctl.c | 20 +++++++++++++++++++- 1 files changed, 19 insertions(+), 1 deletions(-)
fs/nfsd/nfsctl.c +19 -1
@@ -1003,8 +1003,26 @@ static ssize_t __write_ports_addxprt(char *buf) err =svc_create_xprt (nfsd_serv, transport,PF_INET , port,SVC_SOCK_ANONYMOUS );if (err <0 ) -return err; + goto out_err; + + err =svc_create_xprt (nfsd_serv, transport, +PF_INET6 , port,SVC_SOCK_ANONYMOUS ); +if (err <0 && err != -EAFNOSUPPORT ) { +struct svc_xprt *xprt; + xprt =svc_find_xprt (nfsd_serv, transport,PF_INET , port); +if (xprt !=NULL ) { +svc_close_xprt (xprt); +svc_xprt_put (xprt); + } + goto out_err; + } +return 0 ; + +out_err: +/* Decrease the count, but don't shut down the service */ + nfsd_serv->sv_nrthreads--; +return err; }/*
A message that is not in the archive (sent off-list or not yet received): 20100126190422.3368.3981.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]
Re: [PATCH 5/5] NFSD: Create PF_INET6 listener in write_ports
Quoted 11 lines · Chuck Lever
Try to create a
PF_INET6listener for NFSD, if IPv6 is enabled in the kernel.Make sure nfsd_serv's reference count is decreased if
__write_ports_addxprt()failed to create a listener. See__write_ports_addfd().Our current plan is to rely on rpc.nfsd to create appropriate IPv6 listeners when server-side NFS/IPv6 support is desired. Legacy behavior, via the
write_threadsorwrite_svckernel APIs, will remain the same -- only IPv4 listeners are created.
Looks fine, thanks, but:
Quoted 27 lines
Signed-off-by Chuck Lever <[email protected]>---
fs/nfsd/nfsctl.c | 20 +++++++++++++++++++- 1 files changed, 19 insertions(+), 1 deletions(-)fs/nfsd/nfsctl.c +11
-1@@ -1003,8 +1003,26 @@ static ssize_t __write_ports_addxprt(char *buf) err =svc_create_xprt (nfsd_serv, transport,PF_INET , port,SVC_SOCK_ANONYMOUS );if (err <0 ) -return err; + goto out_err; + + err =svc_create_xprt (nfsd_serv, transport, +PF_INET6 , port,SVC_SOCK_ANONYMOUS ); +if (err <0 && err != -EAFNOSUPPORT ) { +struct svc_xprt *xprt; + xprt =svc_find_xprt (nfsd_serv, transport,PF_INET , port); +if (xprt !=NULL ) { +svc_close_xprt (xprt); +svc_xprt_put (xprt); + }
fs/nfsd/nfsctl.c static ssize_t __write_ports_addxprt(char *buf) · line 1026
Quoted 10 lines
fs/nfsd/nfsctl.c +8
-0+ goto out_err; + } +return 0 ; + +out_err: +/* Decrease the count, but don't shut down the service */ + nfsd_serv->sv_nrthreads--; +return err; }
Any objection to moving the extra error-handling to the end, as in the following? If there's no objection, I'll fold it into your last patch.
--b.
fs/nfsd/nfsctl.c +9 -11
@@ -988,6 +988,7 @@ static ssize_t __write_ports_delfd(char *buf)static ssize_t __write_ports_addxprt (char *buf) {char transport[16 ]; +struct svc_xprt *xprt;int port, err;if (sscanf (buf,"%15s %4u" , transport, &port) !=2 )
@@ -1007,18 +1008,15 @@ static ssize_t __write_ports_addxprt(char *buf) err =svc_create_xprt (nfsd_serv, transport,PF_INET6 , port,SVC_SOCK_ANONYMOUS ); -if (err <0 && err != -EAFNOSUPPORT ) { -struct svc_xprt *xprt; - xprt =svc_find_xprt (nfsd_serv, transport,PF_INET , port); -if (xprt !=NULL ) { -svc_close_xprt (xprt); -svc_xprt_put (xprt); - } - goto out_err; - } - +if (err <0 && err != -EAFNOSUPPORT ) + goto out_err_cleanup_inet;return 0 ; - +out_err_cleanup_inet: + xprt =svc_find_xprt (nfsd_serv, transport,PF_INET , port); +if (xprt !=NULL ) { +svc_close_xprt (xprt); +svc_xprt_put (xprt); + } out_err:/* Decrease the count, but don't shut down the service */ nfsd_serv->sv_nrthreads--;
Re: [PATCH 5/5] NFSD: Create PF_INET6 listener in write_ports
Quoted 47 lines · J. Bruce Fields
Quoted 11 lines · Chuck Lever
Try to create a
PF_INET6listener for NFSD, if IPv6 is enabled in the kernel.Make sure nfsd_serv's reference count is decreased if
__write_ports_addxprt()failed to create a listener. See__write_ports_addfd().Our current plan is to rely on rpc.nfsd to create appropriate IPv6 listeners when server-side NFS/IPv6 support is desired. Legacy behavior, via the
write_threadsorwrite_svckernel APIs, will remain the same -- only IPv4 listeners are created.Looks fine, thanks, but:
Quoted 33 lines
Signed-off-by Chuck Lever <[email protected]>---
fs/nfsd/nfsctl.c| 20 +++++++++++++++++++-1 files changed, 19 insertions(+), 1 deletions(-)fs/nfsd/nfsctl.c +15
-1@@ -1003,8 +1003,26 @@ static ssize_t __write_ports_addxprt(char *buf) err =svc_create_xprt (nfsd_serv, transport,PF_INET , port,SVC_SOCK_ANONYMOUS );if (err <0 ) -return err; + goto out_err; + + err =svc_create_xprt (nfsd_serv, transport, +PF_INET6 , port,SVC_SOCK_ANONYMOUS ); +if (err <0 && err != -EAFNOSUPPORT ) { +struct svc_xprt *xprt; + xprt =svc_find_xprt (nfsd_serv, transport,PF_INET , port); +if (xprt !=NULL ) { +svc_close_xprt (xprt); +svc_xprt_put (xprt); + } + goto out_err; + } +return 0 ; +
Quoted 8 lines
fs/nfsd/nfsctl.c static ssize_t __write_ports_addxprt(char · line 1027
Quoted 5 lines
fs/nfsd/nfsctl.c +4
-0+out_err: +/* Decrease the count, but don't shut down the service */ + nfsd_serv->sv_nrthreads--; +return err; }Any objection to moving the extra error-handling to the end, as in the following? If there's no objection, I'll fold it into your last patch.
I guess that's fine, but out_close: would be more succinct than out_err_cleanup_inet, and somewhat more conventional.
Quoted 42 lines
--b.
fs/nfsd/nfsctl.c +9
-11@@ -988,6 +988,7 @@ static ssize_t __write_ports_delfd(char *buf)static ssize_t __write_ports_addxprt (char *buf) {char transport[16 ]; +struct svc_xprt *xprt;int port, err;if (sscanf (buf,"%15s %4u" , transport, &port) !=2 )@@ -1007,18 +1008,15 @@ static ssize_t __write_ports_addxprt(char *buf) err =svc_create_xprt (nfsd_serv, transport,PF_INET6 , port,SVC_SOCK_ANONYMOUS ); -if (err <0 && err != -EAFNOSUPPORT ) { -struct svc_xprt *xprt; - xprt =svc_find_xprt (nfsd_serv, transport,PF_INET , port); -if (xprt !=NULL ) { -svc_close_xprt (xprt); -svc_xprt_put (xprt); - } - goto out_err; - } - +if (err <0 && err != -EAFNOSUPPORT ) + goto out_err_cleanup_inet;return 0 ; - +out_err_cleanup_inet: + xprt =svc_find_xprt (nfsd_serv, transport,PF_INET , port); +if (xprt !=NULL ) { +svc_close_xprt (xprt); +svc_xprt_put (xprt); + }
out_err:/* Decrease the count, but don't shut down the service */ nfsd_serv->sv_nrthreads--;
Signature · 2 lines
Chuck Lever chuck[dot]lever[at]oracle[dot]com
Re: [PATCH 5/5] NFSD: Create PF_INET6 listener in write_ports
Quoted 8 lines · Chuck Lever
Quoted 3 lines · J. Bruce Fields
Any objection to moving the extra error-handling to the end, as in the following? If there's no objection, I'll fold it into your last patch.
I guess that's fine, but
out_close: would be more succinct thanout_err_cleanup_inet, and somewhat more conventional.
Agreed, thanks. Applied, with that change.
--b.
Quoted 51 lines
Quoted 43 lines
--b.
fs/nfsd/nfsctl.c +9
-11@@ -988,6 +988,7 @@ static ssize_t __write_ports_delfd(char *buf)static ssize_t __write_ports_addxprt (char *buf) {char transport[16 ]; +struct svc_xprt *xprt;int port, err;if (sscanf (buf,"%15s %4u" , transport, &port) !=2 )@@ -1007,18 +1008,15 @@ static ssize_t __write_ports_addxprt(char *buf) err =svc_create_xprt (nfsd_serv, transport,PF_INET6 , port,SVC_SOCK_ANONYMOUS ); -if (err <0 && err != -EAFNOSUPPORT ) { -struct svc_xprt *xprt; - xprt =svc_find_xprt (nfsd_serv, transport,PF_INET , port); -if (xprt !=NULL ) { -svc_close_xprt (xprt); -svc_xprt_put (xprt); - } - goto out_err; - } - +if (err <0 && err != -EAFNOSUPPORT ) + goto out_err_cleanup_inet;return 0 ; - +out_err_cleanup_inet: + xprt =svc_find_xprt (nfsd_serv, transport,PF_INET , port); +if (xprt !=NULL ) { +svc_close_xprt (xprt); +svc_xprt_put (xprt); + }
out_err:/* Decrease the count, but don't shut down the service */ nfsd_serv->sv_nrthreads--;Signature · 2 lines
Chuck Lever chuck[dot]lever[at]oracle[dot]com
Quoted 4 lines · Chuck Lever
Hi Bruce-
Repost of last week's IPv6 patch set. I've attempted to address your comments.
Thanks! First four applied. Fifth looks fine too, but see comment on that mail.
--b.
Quoted 23 lines
---
Aime Le Rouzic (1):
NFSD: SupportAF_INET6insvc_addsock()functionChuck Lever (4):
NFSD: CreatePF_INET6listener inwrite_ports
SUNRPC: NFS kernel APIs shouldn't return ENOENT for "transport not found"
SUNRPC: Bury "#ifdef IPV6" insvc_create_xprt()
SUNRPC: Userpc_pton()inip_map_parse()fs/lockd/svc.c | 2 -- fs/nfs/callback.c | 2 -- fs/nfsd/nfsctl.c | 24 ++++++++++++++++++----- net/sunrpc/svc_xprt.c | 9 ++++++++- net/sunrpc/svcauth_unix.c | 47 +++++++++++++++++++++++++-------------------- net/sunrpc/svcsock.c | 2 +- 6 files changed, 54 insertions(+), 32 deletions(-)Signature · 1 line
Chuck Lever <[email protected]>