aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/rpcb_clnt.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-07-01 15:20:55 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-07-08 15:23:10 -0400
commit803a9067e19714ea7b7da760fe92f0d53bfa6994 (patch)
treed95c3f118759ae78754c95f5fc83e187b9d41e56 /net/sunrpc/rpcb_clnt.c
parent0d3a34b48c87a374b37d7a21a60d257d076484f3 (diff)
SUNRPC: Fix an rpcbind breakage for the case of IPv6 lookups
Now that rpcb_next_version has been split into an IPv4 version and an IPv6 version, we Oops when rpcb_call_async attempts to look up the IPv6-specific RPC procedure in rpcb_next_version. Fix the Oops simply by having rpcb_getport_async pass the correct RPC procedure as an argument. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/rpcb_clnt.c')
-rw-r--r--net/sunrpc/rpcb_clnt.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 21c698d7b774..e6fb21b19b86 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -243,10 +243,10 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
243} 243}
244EXPORT_SYMBOL_GPL(rpcb_getport_sync); 244EXPORT_SYMBOL_GPL(rpcb_getport_sync);
245 245
246static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, int version) 246static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc)
247{ 247{
248 struct rpc_message msg = { 248 struct rpc_message msg = {
249 .rpc_proc = rpcb_next_version[version].rpc_proc, 249 .rpc_proc = proc,
250 .rpc_argp = map, 250 .rpc_argp = map,
251 .rpc_resp = &map->r_port, 251 .rpc_resp = &map->r_port,
252 }; 252 };
@@ -271,6 +271,7 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
271void rpcb_getport_async(struct rpc_task *task) 271void rpcb_getport_async(struct rpc_task *task)
272{ 272{
273 struct rpc_clnt *clnt = task->tk_client; 273 struct rpc_clnt *clnt = task->tk_client;
274 struct rpc_procinfo *proc;
274 u32 bind_version; 275 u32 bind_version;
275 struct rpc_xprt *xprt = task->tk_xprt; 276 struct rpc_xprt *xprt = task->tk_xprt;
276 struct rpc_clnt *rpcb_clnt; 277 struct rpc_clnt *rpcb_clnt;
@@ -280,7 +281,6 @@ void rpcb_getport_async(struct rpc_task *task)
280 struct sockaddr *sap = (struct sockaddr *)&addr; 281 struct sockaddr *sap = (struct sockaddr *)&addr;
281 size_t salen; 282 size_t salen;
282 int status; 283 int status;
283 struct rpcb_info *info;
284 284
285 dprintk("RPC: %5u %s(%s, %u, %u, %d)\n", 285 dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
286 task->tk_pid, __func__, 286 task->tk_pid, __func__,
@@ -313,10 +313,12 @@ void rpcb_getport_async(struct rpc_task *task)
313 /* Don't ever use rpcbind v2 for AF_INET6 requests */ 313 /* Don't ever use rpcbind v2 for AF_INET6 requests */
314 switch (sap->sa_family) { 314 switch (sap->sa_family) {
315 case AF_INET: 315 case AF_INET:
316 info = rpcb_next_version; 316 proc = rpcb_next_version[xprt->bind_index].rpc_proc;
317 bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
317 break; 318 break;
318 case AF_INET6: 319 case AF_INET6:
319 info = rpcb_next_version6; 320 proc = rpcb_next_version6[xprt->bind_index].rpc_proc;
321 bind_version = rpcb_next_version6[xprt->bind_index].rpc_vers;
320 break; 322 break;
321 default: 323 default:
322 status = -EAFNOSUPPORT; 324 status = -EAFNOSUPPORT;
@@ -324,14 +326,13 @@ void rpcb_getport_async(struct rpc_task *task)
324 task->tk_pid, __func__); 326 task->tk_pid, __func__);
325 goto bailout_nofree; 327 goto bailout_nofree;
326 } 328 }
327 if (info[xprt->bind_index].rpc_proc == NULL) { 329 if (proc == NULL) {
328 xprt->bind_index = 0; 330 xprt->bind_index = 0;
329 status = -EPFNOSUPPORT; 331 status = -EPFNOSUPPORT;
330 dprintk("RPC: %5u %s: no more getport versions available\n", 332 dprintk("RPC: %5u %s: no more getport versions available\n",
331 task->tk_pid, __func__); 333 task->tk_pid, __func__);
332 goto bailout_nofree; 334 goto bailout_nofree;
333 } 335 }
334 bind_version = info[xprt->bind_index].rpc_vers;
335 336
336 dprintk("RPC: %5u %s: trying rpcbind version %u\n", 337 dprintk("RPC: %5u %s: trying rpcbind version %u\n",
337 task->tk_pid, __func__, bind_version); 338 task->tk_pid, __func__, bind_version);
@@ -361,7 +362,7 @@ void rpcb_getport_async(struct rpc_task *task)
361 map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR); 362 map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR);
362 map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */ 363 map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */
363 364
364 child = rpcb_call_async(rpcb_clnt, map, xprt->bind_index); 365 child = rpcb_call_async(rpcb_clnt, map, proc);
365 rpc_release_client(rpcb_clnt); 366 rpc_release_client(rpcb_clnt);
366 if (IS_ERR(child)) { 367 if (IS_ERR(child)) {
367 status = -EIO; 368 status = -EIO;