* [PATCH 01/17] SUNRPC: Pass a family argument to svc_register()
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2009-03-03 22:32 ` Chuck Lever
2009-03-03 22:32 ` [PATCH 02/17] SUNRPC: svc_setup_socket() gets protocol family from socket Chuck Lever
` (15 subsequent siblings)
16 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:32 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +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..cefad59 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 address 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] 30+ messages in thread* [PATCH 02/17] SUNRPC: svc_setup_socket() gets protocol family from socket
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-03 22:32 ` [PATCH 01/17] SUNRPC: Pass a family argument to svc_register() Chuck Lever
@ 2009-03-03 22:32 ` Chuck Lever
2009-03-03 22:32 ` [PATCH 03/17] SUNRPC: Change svc_create_xprt() to take a @family argument Chuck Lever
` (14 subsequent siblings)
16 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:32 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +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] 30+ messages in thread* [PATCH 03/17] SUNRPC: Change svc_create_xprt() to take a @family argument
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-03 22:32 ` [PATCH 01/17] SUNRPC: Pass a family argument to svc_register() Chuck Lever
2009-03-03 22:32 ` [PATCH 02/17] SUNRPC: svc_setup_socket() gets protocol family from socket Chuck Lever
@ 2009-03-03 22:32 ` Chuck Lever
2009-03-03 22:32 ` [PATCH 04/17] SUNRPC: Remove @family argument from svc_create() and svc_create_pooled() Chuck Lever
` (13 subsequent siblings)
16 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:32 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +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.
We want to pass the listener's protocol family to svc_create_xprt(),
not to svc_create(). That way, transport creation can be retried if
no IPv6 support is available on the system at run-time.
The old way (passing the protocol family to svc_create() ) means we
would have to destroy the svc_serv and create a new one with PF_INET
before calling svc_create_xprt() again.
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 0127dac..879c701 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 e588df5..3772081 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] 30+ messages in thread* [PATCH 04/17] SUNRPC: Remove @family argument from svc_create() and svc_create_pooled()
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (2 preceding siblings ...)
2009-03-03 22:32 ` [PATCH 03/17] SUNRPC: Change svc_create_xprt() to take a @family argument Chuck Lever
@ 2009-03-03 22:32 ` Chuck Lever
2009-03-03 22:32 ` [PATCH 05/17] NFS: Revert creation of IPv6 listeners for lockd and NFSv4 callbacks Chuck Lever
` (12 subsequent siblings)
16 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:32 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +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 cefad59..6cc3c62 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] 30+ messages in thread* [PATCH 05/17] NFS: Revert creation of IPv6 listeners for lockd and NFSv4 callbacks
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (3 preceding siblings ...)
2009-03-03 22:32 ` [PATCH 04/17] SUNRPC: Remove @family argument from svc_create() and svc_create_pooled() Chuck Lever
@ 2009-03-03 22:32 ` Chuck Lever
2009-03-03 22:32 ` [PATCH 06/17] SUNRPC: Set IPV6ONLY flag on PF_INET6 RPC listener sockets Chuck Lever
` (11 subsequent siblings)
16 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:32 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +Cc: linux-nfs
I'm about to change over to separate AF_INET and AF_INET6 listeners.
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] 30+ messages in thread* [PATCH 06/17] SUNRPC: Set IPV6ONLY flag on PF_INET6 RPC listener sockets
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (4 preceding siblings ...)
2009-03-03 22:32 ` [PATCH 05/17] NFS: Revert creation of IPv6 listeners for lockd and NFSv4 callbacks Chuck Lever
@ 2009-03-03 22:32 ` Chuck Lever
[not found] ` <20090303223254.2933.70364.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-03 22:33 ` [PATCH 07/17] SUNRPC: Use IPv4 loopback for registering AF_INET6 kernel RPC services Chuck Lever
` (10 subsequent siblings)
16 siblings, 1 reply; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:32 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +Cc: linux-nfs
We are about to convert to using separate RPC listener sockets for
AF_INET and AF_INET6. This echoes the way IPv6 is handled in user
space by TI-RPC, and eliminates the need to worry about mapped IPv4
AF_INET6 addresses when doing address comparisons.
Start by setting the IPV6ONLY flag on 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] 30+ messages in thread* [PATCH 07/17] SUNRPC: Use IPv4 loopback for registering AF_INET6 kernel RPC services
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (5 preceding siblings ...)
2009-03-03 22:32 ` [PATCH 06/17] SUNRPC: Set IPV6ONLY flag on PF_INET6 RPC listener sockets Chuck Lever
@ 2009-03-03 22:33 ` Chuck Lever
2009-03-03 22:33 ` [PATCH 08/17] SUNRPC: Don't return EPROTONOSUPPORT in svc_register()'s helpers Chuck Lever
` (9 subsequent siblings)
16 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:33 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +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] 30+ messages in thread* [PATCH 08/17] SUNRPC: Don't return EPROTONOSUPPORT in svc_register()'s helpers
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (6 preceding siblings ...)
2009-03-03 22:33 ` [PATCH 07/17] SUNRPC: Use IPv4 loopback for registering AF_INET6 kernel RPC services Chuck Lever
@ 2009-03-03 22:33 ` Chuck Lever
[not found] ` <20090303223309.2933.51773.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-03 22:33 ` [PATCH 09/17] SUNRPC: Clean up address type casts in rpcb_v4_register() Chuck Lever
` (8 subsequent siblings)
16 siblings, 1 reply; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:33 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +Cc: linux-nfs
The RPC client returns -EPROTONOSUPPORT if there is a protocol version
mismatch (ie the remote RPC server doesn't support the RPC protocol
version sent by the client).
Helpers for the svc_register() function return -EPROTONOSUPPORT if they
don't recognize the passed-in IPPROTO_ value.
These are two entirely different failure modes.
Have the helpers return -ENOPROTOOPT instead of -ENOPROTOOPT. This will
allow callers to determine more precisely what the underlying problem is,
and decide to report or recover appropriately.
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 | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 6cc3c62..c89f04e 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -749,7 +749,7 @@ static int __svc_rpcb_register4(const u32 program, const u32 version,
netid = RPCBIND_NETID_TCP;
break;
default:
- return -EPROTONOSUPPORT;
+ return -ENOPROTOOPT;
}
return rpcb_v4_register(program, version,
@@ -785,7 +785,7 @@ static int __svc_rpcb_register6(const u32 program, const u32 version,
netid = RPCBIND_NETID_TCP6;
break;
default:
- return -EPROTONOSUPPORT;
+ return -ENOPROTOOPT;
}
return rpcb_v4_register(program, version,
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 09/17] SUNRPC: Clean up address type casts in rpcb_v4_register()
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (7 preceding siblings ...)
2009-03-03 22:33 ` [PATCH 08/17] SUNRPC: Don't return EPROTONOSUPPORT in svc_register()'s helpers Chuck Lever
@ 2009-03-03 22:33 ` Chuck Lever
2009-03-03 22:33 ` [PATCH 10/17] SUNRPC: Use "0" as r_owner Chuck Lever
` (7 subsequent siblings)
16 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:33 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +Cc: linux-nfs
Clean up: move the details of the sockaddr type casting to the 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] 30+ messages in thread* [PATCH 10/17] SUNRPC: Use "0" as r_owner
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (8 preceding siblings ...)
2009-03-03 22:33 ` [PATCH 09/17] SUNRPC: Clean up address type casts in rpcb_v4_register() Chuck Lever
@ 2009-03-03 22:33 ` Chuck Lever
[not found] ` <20090303223324.2933.57002.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-03 22:33 ` [PATCH 11/17] SUNRPC: Allow callers to pass rpcb_v4_register a NULL address Chuck Lever
` (6 subsequent siblings)
16 siblings, 1 reply; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:33 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +Cc: linux-nfs
It turns out that, despite the spec, rpcbind interprets the string
passed in the r_owner argument for SET and UNSET requests. It expects
it to be a numeric UID, rather than an arbitrary string.
Change the kernel's r_owner string to be "0".
This is a documentation change only.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/rpcb_clnt.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 317eb8a..0a3b8f5 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -63,9 +63,11 @@ enum {
* r_owner
*
* The "owner" is allowed to unset a service in the rpcbind database.
- * We always use the following (arbitrary) fixed string.
+ * rpcbind maps this string to a local user name via a passwd lookup
+ * for AF_LOCAL SET/UNSET requests, but via the network (ie how the
+ * kernel registers its services) it is pretty much ignored.
*/
-#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 *);
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 11/17] SUNRPC: Allow callers to pass rpcb_v4_register a NULL address
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (9 preceding siblings ...)
2009-03-03 22:33 ` [PATCH 10/17] SUNRPC: Use "0" as r_owner Chuck Lever
@ 2009-03-03 22:33 ` Chuck Lever
2009-03-03 22:33 ` [PATCH 12/17] SUNRPC: Simplify svc_unregister() Chuck Lever
` (5 subsequent siblings)
16 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:33 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +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". 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 0a3b8f5..cccc676 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -257,8 +257,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;
@@ -285,8 +285,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;
@@ -314,6 +314,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
@@ -331,10 +345,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
@@ -369,11 +384,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] 30+ messages in thread* [PATCH 12/17] SUNRPC: Simplify svc_unregister()
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (10 preceding siblings ...)
2009-03-03 22:33 ` [PATCH 11/17] SUNRPC: Allow callers to pass rpcb_v4_register a NULL address Chuck Lever
@ 2009-03-03 22:33 ` Chuck Lever
2009-03-03 22:33 ` [PATCH 13/17] SUNRPC: Simplify kernel RPC service registration Chuck Lever
` (4 subsequent siblings)
16 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:33 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +Cc: linux-nfs
We now have some evidence that PMAP_UNSET clears only "inet" entries,
and not "inet6" entries, in the rpcbind database. 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.
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>
Tested-and-Acked-by: Steve Dickson <steved@redhat.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 c89f04e..f1e0ad8 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] 30+ messages in thread* [PATCH 13/17] SUNRPC: Simplify kernel RPC service registration
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (11 preceding siblings ...)
2009-03-03 22:33 ` [PATCH 12/17] SUNRPC: Simplify svc_unregister() Chuck Lever
@ 2009-03-03 22:33 ` Chuck Lever
2009-03-03 22:33 ` [PATCH 14/17] SUNRPC: rpcb_register() should handle errors silently Chuck Lever
` (3 subsequent siblings)
16 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:33 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +Cc: linux-nfs
The kernel registers RPC services with the local portmapper with an
rpcbind SET upcall to the local portmapper. Traditionally, this used
rpcbind v2, but registering RPC services that support IPv6 requires
rpcbind v3 or v4.
Since we now want separate PF_INET and PF_INET6 listeners for each
kernel RPC service, svc_register() will do only one of those
registrations at a time.
For PF_INET, it tries an rpcb v4 SET upcall first; if that fails, it
does a legacy portmap SET. This makes it entirely backwards
compatible with legacy user space, but allows a proper v4 SET to be
used if rpcbind is available.
For PF_INET6, it does an rpcb v4 SET upcall. If that fails, it fails
the registration, and thus the transport creation. This let's the
kernel detect if user space is able to support IPv6 RPC services.
This provides complete backwards compatibilty with legacy user space
that only supports rpcbind v2. The only down-side is that registering
a new kernel RPC service may take an extra exchange with the local
portmapper on legacy systems, but this is an infrequent operation, so
it shouldn't be consequential.
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 | 79 +++++++++++++++++++++++-------------------------------
1 files changed, 34 insertions(+), 45 deletions(-)
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index f1e0ad8..949164d 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -718,8 +718,6 @@ svc_exit_thread(struct svc_rqst *rqstp)
}
EXPORT_SYMBOL_GPL(svc_exit_thread);
-#ifdef CONFIG_SUNRPC_REGISTER_V4
-
/*
* Register an "inet" protocol family netid with the local
* rpcbind daemon via an rpcbind v4 SET request.
@@ -734,12 +732,13 @@ static int __svc_rpcb_register4(const u32 program, const u32 version,
const unsigned short protocol,
const unsigned short port)
{
- struct sockaddr_in sin = {
+ const struct sockaddr_in sin = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(INADDR_ANY),
.sin_port = htons(port),
};
- char *netid;
+ const char *netid;
+ int error;
switch (protocol) {
case IPPROTO_UDP:
@@ -752,10 +751,20 @@ static int __svc_rpcb_register4(const u32 program, const u32 version,
return -ENOPROTOOPT;
}
- return rpcb_v4_register(program, version,
- (struct sockaddr *)&sin, netid);
+ error = rpcb_v4_register(program, version,
+ (const struct sockaddr *)&sin, netid);
+
+ /*
+ * User space didn't support rpcbind v4, so retry this
+ * registration request with the legacy rpcbind v2 protocol.
+ */
+ if (error == -EPROTONOSUPPORT)
+ error = rpcb_register(program, version, protocol, port);
+
+ return error;
}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
/*
* Register an "inet6" protocol family netid with the local
* rpcbind daemon via an rpcbind v4 SET request.
@@ -770,12 +779,13 @@ static int __svc_rpcb_register6(const u32 program, const u32 version,
const unsigned short protocol,
const unsigned short port)
{
- struct sockaddr_in6 sin6 = {
+ const struct sockaddr_in6 sin6 = {
.sin6_family = AF_INET6,
.sin6_addr = IN6ADDR_ANY_INIT,
.sin6_port = htons(port),
};
- char *netid;
+ const char *netid;
+ int error;
switch (protocol) {
case IPPROTO_UDP:
@@ -788,9 +798,19 @@ static int __svc_rpcb_register6(const u32 program, const u32 version,
return -ENOPROTOOPT;
}
- return rpcb_v4_register(program, version,
- (struct sockaddr *)&sin6, netid);
+ error = rpcb_v4_register(program, version,
+ (const struct sockaddr *)&sin6, netid);
+
+ /*
+ * User space didn't support rpcbind version 4, so we won't
+ * use a PF_INET6 listener.
+ */
+ if (error == -EPROTONOSUPPORT)
+ error = -EAFNOSUPPORT;
+
+ return error;
}
+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
/*
* Register a kernel RPC service via rpcbind version 4.
@@ -809,48 +829,17 @@ static int __svc_register(const u32 program, const u32 version,
case PF_INET:
return __svc_rpcb_register4(program, version,
protocol, port);
+ break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case PF_INET6:
- error = __svc_rpcb_register6(program, version,
+ return__svc_rpcb_register6(program, version,
protocol, port);
- if (error < 0)
- return error;
-
- /*
- * Work around bug in some versions of Linux rpcbind
- * which don't allow registration of both inet and
- * inet6 netids.
- *
- * Error return ignored for now.
- */
- __svc_rpcb_register4(program, version,
- protocol, port);
- return 0;
+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
}
return -EAFNOSUPPORT;
}
-#else /* CONFIG_SUNRPC_REGISTER_V4 */
-
-/*
- * Register a kernel RPC service via rpcbind version 2.
- *
- * Returns zero on success; a negative errno value is returned
- * if any error occurs.
- */
-static int __svc_register(const u32 program, const u32 version,
- const int family,
- const unsigned short protocol,
- const unsigned short port)
-{
- if (family != PF_INET)
- return -EAFNOSUPPORT;
-
- return rpcb_register(program, version, protocol, port);
-}
-
-#endif /* CONFIG_SUNRPC_REGISTER_V4 */
-
/**
* svc_register - register an RPC service with the local portmapper
* @serv: svc_serv struct for the service to register
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 14/17] SUNRPC: rpcb_register() should handle errors silently
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (12 preceding siblings ...)
2009-03-03 22:33 ` [PATCH 13/17] SUNRPC: Simplify kernel RPC service registration Chuck Lever
@ 2009-03-03 22:33 ` Chuck Lever
2009-03-03 22:34 ` [PATCH 15/17] SUNRPC: Remove CONFIG_SUNRPC_REGISTER_V4 Chuck Lever
` (2 subsequent siblings)
16 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:33 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +Cc: linux-nfs
Move error reporting for RPC registration to rpcb_register's caller.
This way the caller can choose to recover silently from certain
errors, but report errors it does not recognize. Error reporting
for kernel RPC service registration is now handled in one place.
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 | 2 +-
net/sunrpc/svc.c | 18 +++++++++++-------
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index cccc676..42e9b96 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -189,7 +189,7 @@ static int rpcb_register_call(const u32 version, struct rpc_message *msg)
error = PTR_ERR(rpcb_clnt);
if (error < 0) {
- printk(KERN_WARNING "RPC: failed to contact local rpcbind "
+ dprintk("RPC: failed to contact local rpcbind "
"server (errno %d).\n", -error);
return error;
}
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 949164d..dc50159 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -818,26 +818,30 @@ static int __svc_rpcb_register6(const u32 program, const u32 version,
* Returns zero on success; a negative errno value is returned
* if any error occurs.
*/
-static int __svc_register(const u32 program, const u32 version,
+static int __svc_register(const char *progname,
+ const u32 program, const u32 version,
const int family,
const unsigned short protocol,
const unsigned short port)
{
- int error;
+ int error = -EAFNOSUPPORT;
switch (family) {
case PF_INET:
- return __svc_rpcb_register4(program, version,
+ error = __svc_rpcb_register4(program, version,
protocol, port);
break;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case PF_INET6:
- return__svc_rpcb_register6(program, version,
+ error = __svc_rpcb_register6(program, version,
protocol, port);
#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
}
- return -EAFNOSUPPORT;
+ if (error < 0)
+ printk(KERN_WARNING "svc: failed to register %sv%u RPC "
+ "service (errno %d).\n", progname, version, -error);
+ return error;
}
/**
@@ -875,8 +879,8 @@ int svc_register(const struct svc_serv *serv, const int family,
if (progp->pg_vers[i]->vs_hidden)
continue;
- error = __svc_register(progp->pg_prog, i,
- family, proto, port);
+ error = __svc_register(progp->pg_name, progp->pg_prog,
+ i, family, proto, port);
if (error < 0)
break;
}
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 15/17] SUNRPC: Remove CONFIG_SUNRPC_REGISTER_V4
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (13 preceding siblings ...)
2009-03-03 22:33 ` [PATCH 14/17] SUNRPC: rpcb_register() should handle errors silently Chuck Lever
@ 2009-03-03 22:34 ` Chuck Lever
2009-03-03 22:34 ` [PATCH 16/17] lockd: Start PF_INET6 listener only if IPv6 support is available Chuck Lever
2009-03-03 22:34 ` [PATCH 17/17] NFS: Start PF_INET6 callback listener only if IPv6 support is available Chuck Lever
16 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:34 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +Cc: linux-nfs
We just augmented the kernel's RPC service registration code so that
it automatically adjusts to what is supported in user space. Thus we
no longer need the kernel configuration option to enable registering
RPC services with v4 -- it's all done automatically.
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/Kconfig | 22 ----------------------
1 files changed, 0 insertions(+), 22 deletions(-)
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index 5592883..afd91c7 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -17,28 +17,6 @@ config SUNRPC_XPRT_RDMA
If unsure, say N.
-config SUNRPC_REGISTER_V4
- bool "Register local RPC services via rpcbind v4 (EXPERIMENTAL)"
- depends on SUNRPC && EXPERIMENTAL
- default n
- help
- Sun added support for registering RPC services at an IPv6
- address by creating two new versions of the rpcbind protocol
- (RFC 1833).
-
- This option enables support in the kernel RPC server for
- registering kernel RPC services via version 4 of the rpcbind
- protocol. If you enable this option, you must run a portmapper
- daemon that supports rpcbind protocol version 4.
-
- Serving NFS over IPv6 from knfsd (the kernel's NFS server)
- requires that you enable this option and use a portmapper that
- supports rpcbind version 4.
-
- If unsure, say N to get traditional behavior (register kernel
- RPC services using only rpcbind version 2). Distributions
- using the legacy Linux portmapper daemon must say N here.
-
config RPCSEC_GSS_KRB5
tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)"
depends on SUNRPC && EXPERIMENTAL
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 16/17] lockd: Start PF_INET6 listener only if IPv6 support is available
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (14 preceding siblings ...)
2009-03-03 22:34 ` [PATCH 15/17] SUNRPC: Remove CONFIG_SUNRPC_REGISTER_V4 Chuck Lever
@ 2009-03-03 22:34 ` Chuck Lever
[not found] ` <20090303223410.2933.90223.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-03-03 22:34 ` [PATCH 17/17] NFS: Start PF_INET6 callback listener only if IPv6 support is available Chuck Lever
16 siblings, 1 reply; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:34 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +Cc: linux-nfs
Apparently a lot of people need to disable IPv6 completely on their
distributor-built systems, which have CONFIG_IPV6_MODULE enabled.
They do this by blacklisting the ipv6.ko module. This causes the
creation of the lockd service listener to fail if CONFIG_IPV6_MODULE
is set, but the module cannot be loaded.
Now that the kernel's PF_INET6 RPC listeners are completely separate
from PF_INET listeners, we can always start PF_INET. Then lockd can
try to start PF_INET6, but it isn't required to be available.
Note this has the added benefit that NLM callbacks from AF_INET6
servers will never come from AF_INET remotes. We no longer have to
worry about matching mapped IPv4 addresses to AF_INET when comparing
addresses.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/lockd/svc.c | 28 ++++++++++++++++++++--------
1 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 566932b..4342b41 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -194,19 +194,29 @@ lockd(void *vrqstp)
}
static int create_lockd_listener(struct svc_serv *serv, char *name,
- unsigned short port)
+ const int family, const unsigned short port)
{
struct svc_xprt *xprt;
- xprt = svc_find_xprt(serv, name, 0, 0);
+ xprt = svc_find_xprt(serv, name, family, 0);
if (xprt == NULL)
- return svc_create_xprt(serv, name, PF_INET,
- port, SVC_SOCK_DEFAULTS);
-
+ return svc_create_xprt(serv, name, family, port,
+ SVC_SOCK_DEFAULTS);
svc_xprt_put(xprt);
return 0;
}
+static int create_lockd_family(struct svc_serv *serv, const int family)
+{
+ int err;
+
+ err = create_lockd_listener(serv, "udp", family, nlm_udpport);
+ if (err < 0)
+ return err;
+
+ return create_lockd_listener(serv, "tcp", family, nlm_tcpport);
+}
+
/*
* Ensure there are active UDP and TCP listeners for lockd.
*
@@ -222,13 +232,15 @@ static int make_socks(struct svc_serv *serv)
static int warned;
int err;
- err = create_lockd_listener(serv, "udp", nlm_udpport);
+ err = create_lockd_family(serv, PF_INET);
if (err < 0)
goto out_err;
- err = create_lockd_listener(serv, "tcp", nlm_tcpport);
- if (err < 0)
+#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;
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCH 17/17] NFS: Start PF_INET6 callback listener only if IPv6 support is available
[not found] ` <20090303220539.2933.15015.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
` (15 preceding siblings ...)
2009-03-03 22:34 ` [PATCH 16/17] lockd: Start PF_INET6 listener only if IPv6 support is available Chuck Lever
@ 2009-03-03 22:34 ` Chuck Lever
16 siblings, 0 replies; 30+ messages in thread
From: Chuck Lever @ 2009-03-03 22:34 UTC (permalink / raw)
To: trond.myklebust, bfields, steved; +Cc: linux-nfs
Apparently a lot of people need to disable IPv6 completely on their
distributor-built systems, which have CONFIG_IPV6_MODULE enabled.
They do this by blacklisting the ipv6.ko module. This causes the
creation of the NFSv4 callback service listener to fail if
CONFIG_IPV6_MODULE is set, but the module cannot be loaded.
Now that the kernel's PF_INET6 RPC listeners are completely separate
from PF_INET listeners, we can always start PF_INET. Then the NFS
client can try to start a PF_INET6 listener, but it isn't required
to be available.
Note this has the added benefit that NFS callbacks from AF_INET6
servers will never come from AF_INET remotes. We no longer have to
worry about matching mapped IPv4 addresses to AF_INET when comparing
addresses.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfs/callback.c | 12 ++++++++++++
fs/nfs/callback.h | 1 +
fs/nfs/nfs4state.c | 10 ++++++++--
3 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 0ef47df..a886e69 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -38,6 +38,7 @@ static struct svc_program nfs4_callback_program;
unsigned int nfs_callback_set_tcpport;
unsigned short nfs_callback_tcpport;
+unsigned short nfs_callback_tcpport6;
static const int nfs_set_port_min = 0;
static const int nfs_set_port_max = 65535;
@@ -119,6 +120,17 @@ int nfs_callback_up(void)
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) {
+ nfs_callback_tcpport6 = ret;
+ dprintk("NFS: Callback listener port = %u (af %u)\n",
+ nfs_callback_tcpport6, PF_INET6);
+ } else if (ret != -EAFNOSUPPORT)
+ goto out_err;
+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
+
nfs_callback_info.rqst = svc_prepare_thread(serv, &serv->sv_pools[0]);
if (IS_ERR(nfs_callback_info.rqst)) {
ret = PTR_ERR(nfs_callback_info.rqst);
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index bb25d21..e110e28 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -72,5 +72,6 @@ extern void nfs_callback_down(void);
extern unsigned int nfs_callback_set_tcpport;
extern unsigned short nfs_callback_tcpport;
+extern unsigned short nfs_callback_tcpport6;
#endif /* __LINUX_FS_NFS_CALLBACK_H */
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 2022fe4..0298e90 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -62,8 +62,14 @@ static LIST_HEAD(nfs4_clientid_list);
static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred)
{
- int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK,
- nfs_callback_tcpport, cred);
+ unsigned short port;
+ int status;
+
+ port = nfs_callback_tcpport;
+ if (clp->cl_addr.ss_family == AF_INET6)
+ port = nfs_callback_tcpport6;
+
+ status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred);
if (status == 0)
status = nfs4_proc_setclientid_confirm(clp, cred);
if (status == 0)
^ permalink raw reply related [flat|nested] 30+ messages in thread