diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-07-01 15:20:55 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-07-08 15:23:10 -0400 |
commit | 803a9067e19714ea7b7da760fe92f0d53bfa6994 (patch) | |
tree | d95c3f118759ae78754c95f5fc83e187b9d41e56 | |
parent | 0d3a34b48c87a374b37d7a21a60d257d076484f3 (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>
-rw-r--r-- | net/sunrpc/rpcb_clnt.c | 17 |
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 | } |
244 | EXPORT_SYMBOL_GPL(rpcb_getport_sync); | 244 | EXPORT_SYMBOL_GPL(rpcb_getport_sync); |
245 | 245 | ||
246 | static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, int version) | 246 | static 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 | |||
271 | void rpcb_getport_async(struct rpc_task *task) | 271 | void 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; |