diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2009-03-18 20:48:06 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-03-28 16:02:43 -0400 |
commit | f738f5170367b367e38b2d75a413e7b3c52d46a5 (patch) | |
tree | 3552d487e54e8c555e4f7083194d46b6eb95fc66 | |
parent | eb16e907781a9da7f272a3e8284c26bc4e4aeb9d (diff) |
NFS: Start PF_INET6 callback listener only if IPv6 support is available
Apparently a lot of people need to disable IPv6 completely on their
distributor-built systems, which have CONFIG_IPV6_MODULE enabled at
build time.
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.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/callback.c | 12 | ||||
-rw-r--r-- | fs/nfs/callback.h | 1 | ||||
-rw-r--r-- | 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 0ef47dff89be..a886e692ddd0 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -38,6 +38,7 @@ static struct svc_program nfs4_callback_program; | |||
38 | 38 | ||
39 | unsigned int nfs_callback_set_tcpport; | 39 | unsigned int nfs_callback_set_tcpport; |
40 | unsigned short nfs_callback_tcpport; | 40 | unsigned short nfs_callback_tcpport; |
41 | unsigned short nfs_callback_tcpport6; | ||
41 | static const int nfs_set_port_min = 0; | 42 | static const int nfs_set_port_min = 0; |
42 | static const int nfs_set_port_max = 65535; | 43 | static const int nfs_set_port_max = 65535; |
43 | 44 | ||
@@ -119,6 +120,17 @@ int nfs_callback_up(void) | |||
119 | dprintk("NFS: Callback listener port = %u (af %u)\n", | 120 | dprintk("NFS: Callback listener port = %u (af %u)\n", |
120 | nfs_callback_tcpport, PF_INET); | 121 | nfs_callback_tcpport, PF_INET); |
121 | 122 | ||
123 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
124 | ret = svc_create_xprt(serv, "tcp", PF_INET6, | ||
125 | nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); | ||
126 | if (ret > 0) { | ||
127 | nfs_callback_tcpport6 = ret; | ||
128 | dprintk("NFS: Callback listener port = %u (af %u)\n", | ||
129 | nfs_callback_tcpport6, PF_INET6); | ||
130 | } else if (ret != -EAFNOSUPPORT) | ||
131 | goto out_err; | ||
132 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | ||
133 | |||
122 | nfs_callback_info.rqst = svc_prepare_thread(serv, &serv->sv_pools[0]); | 134 | nfs_callback_info.rqst = svc_prepare_thread(serv, &serv->sv_pools[0]); |
123 | if (IS_ERR(nfs_callback_info.rqst)) { | 135 | if (IS_ERR(nfs_callback_info.rqst)) { |
124 | ret = PTR_ERR(nfs_callback_info.rqst); | 136 | ret = PTR_ERR(nfs_callback_info.rqst); |
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index bb25d2135ff1..e110e286a262 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h | |||
@@ -72,5 +72,6 @@ extern void nfs_callback_down(void); | |||
72 | 72 | ||
73 | extern unsigned int nfs_callback_set_tcpport; | 73 | extern unsigned int nfs_callback_set_tcpport; |
74 | extern unsigned short nfs_callback_tcpport; | 74 | extern unsigned short nfs_callback_tcpport; |
75 | extern unsigned short nfs_callback_tcpport6; | ||
75 | 76 | ||
76 | #endif /* __LINUX_FS_NFS_CALLBACK_H */ | 77 | #endif /* __LINUX_FS_NFS_CALLBACK_H */ |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 2022fe47966f..0298e909559f 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -62,8 +62,14 @@ static LIST_HEAD(nfs4_clientid_list); | |||
62 | 62 | ||
63 | static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred) | 63 | static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred) |
64 | { | 64 | { |
65 | int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, | 65 | unsigned short port; |
66 | nfs_callback_tcpport, cred); | 66 | int status; |
67 | |||
68 | port = nfs_callback_tcpport; | ||
69 | if (clp->cl_addr.ss_family == AF_INET6) | ||
70 | port = nfs_callback_tcpport6; | ||
71 | |||
72 | status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred); | ||
67 | if (status == 0) | 73 | if (status == 0) |
68 | status = nfs4_proc_setclientid_confirm(clp, cred); | 74 | status = nfs4_proc_setclientid_confirm(clp, cred); |
69 | if (status == 0) | 75 | if (status == 0) |