diff options
Diffstat (limited to 'net/sunrpc/rpcb_clnt.c')
-rw-r--r-- | net/sunrpc/rpcb_clnt.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 6c7aa8a1f0c6..d1740dbab991 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
@@ -12,6 +12,8 @@ | |||
12 | * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> | 12 | * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/module.h> | ||
16 | |||
15 | #include <linux/types.h> | 17 | #include <linux/types.h> |
16 | #include <linux/socket.h> | 18 | #include <linux/socket.h> |
17 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
@@ -184,8 +186,8 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, | |||
184 | .program = &rpcb_program, | 186 | .program = &rpcb_program, |
185 | .version = version, | 187 | .version = version, |
186 | .authflavor = RPC_AUTH_UNIX, | 188 | .authflavor = RPC_AUTH_UNIX, |
187 | .flags = (RPC_CLNT_CREATE_ONESHOT | | 189 | .flags = (RPC_CLNT_CREATE_NOPING | |
188 | RPC_CLNT_CREATE_NOPING), | 190 | RPC_CLNT_CREATE_INTR), |
189 | }; | 191 | }; |
190 | 192 | ||
191 | ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT); | 193 | ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT); |
@@ -238,6 +240,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) | |||
238 | 240 | ||
239 | error = rpc_call_sync(rpcb_clnt, &msg, 0); | 241 | error = rpc_call_sync(rpcb_clnt, &msg, 0); |
240 | 242 | ||
243 | rpc_shutdown_client(rpcb_clnt); | ||
241 | if (error < 0) | 244 | if (error < 0) |
242 | printk(KERN_WARNING "RPC: failed to contact local rpcbind " | 245 | printk(KERN_WARNING "RPC: failed to contact local rpcbind " |
243 | "server (errno %d).\n", -error); | 246 | "server (errno %d).\n", -error); |
@@ -246,21 +249,20 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) | |||
246 | return error; | 249 | return error; |
247 | } | 250 | } |
248 | 251 | ||
249 | #ifdef CONFIG_ROOT_NFS | ||
250 | /** | 252 | /** |
251 | * rpcb_getport_external - obtain the port for an RPC service on a given host | 253 | * rpcb_getport_sync - obtain the port for an RPC service on a given host |
252 | * @sin: address of remote peer | 254 | * @sin: address of remote peer |
253 | * @prog: RPC program number to bind | 255 | * @prog: RPC program number to bind |
254 | * @vers: RPC version number to bind | 256 | * @vers: RPC version number to bind |
255 | * @prot: transport protocol to use to make this request | 257 | * @prot: transport protocol to use to make this request |
256 | * | 258 | * |
257 | * Called from outside the RPC client in a synchronous task context. | 259 | * Called from outside the RPC client in a synchronous task context. |
260 | * Uses default timeout parameters specified by underlying transport. | ||
258 | * | 261 | * |
259 | * For now, this supports only version 2 queries, but is used only by | 262 | * XXX: Needs to support IPv6, and rpcbind versions 3 and 4 |
260 | * mount_clnt for NFS_ROOT. | ||
261 | */ | 263 | */ |
262 | int rpcb_getport_external(struct sockaddr_in *sin, __u32 prog, | 264 | int rpcb_getport_sync(struct sockaddr_in *sin, __u32 prog, |
263 | __u32 vers, int prot) | 265 | __u32 vers, int prot) |
264 | { | 266 | { |
265 | struct rpcbind_args map = { | 267 | struct rpcbind_args map = { |
266 | .r_prog = prog, | 268 | .r_prog = prog, |
@@ -277,15 +279,16 @@ int rpcb_getport_external(struct sockaddr_in *sin, __u32 prog, | |||
277 | char hostname[40]; | 279 | char hostname[40]; |
278 | int status; | 280 | int status; |
279 | 281 | ||
280 | dprintk("RPC: rpcb_getport_external(%u.%u.%u.%u, %u, %u, %d)\n", | 282 | dprintk("RPC: %s(" NIPQUAD_FMT ", %u, %u, %d)\n", |
281 | NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot); | 283 | __FUNCTION__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot); |
282 | 284 | ||
283 | sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr)); | 285 | sprintf(hostname, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr)); |
284 | rpcb_clnt = rpcb_create(hostname, (struct sockaddr *)sin, prot, 2, 0); | 286 | rpcb_clnt = rpcb_create(hostname, (struct sockaddr *)sin, prot, 2, 0); |
285 | if (IS_ERR(rpcb_clnt)) | 287 | if (IS_ERR(rpcb_clnt)) |
286 | return PTR_ERR(rpcb_clnt); | 288 | return PTR_ERR(rpcb_clnt); |
287 | 289 | ||
288 | status = rpc_call_sync(rpcb_clnt, &msg, 0); | 290 | status = rpc_call_sync(rpcb_clnt, &msg, 0); |
291 | rpc_shutdown_client(rpcb_clnt); | ||
289 | 292 | ||
290 | if (status >= 0) { | 293 | if (status >= 0) { |
291 | if (map.r_port != 0) | 294 | if (map.r_port != 0) |
@@ -294,16 +297,16 @@ int rpcb_getport_external(struct sockaddr_in *sin, __u32 prog, | |||
294 | } | 297 | } |
295 | return status; | 298 | return status; |
296 | } | 299 | } |
297 | #endif | 300 | EXPORT_SYMBOL_GPL(rpcb_getport_sync); |
298 | 301 | ||
299 | /** | 302 | /** |
300 | * rpcb_getport - obtain the port for a given RPC service on a given host | 303 | * rpcb_getport_async - obtain the port for a given RPC service on a given host |
301 | * @task: task that is waiting for portmapper request | 304 | * @task: task that is waiting for portmapper request |
302 | * | 305 | * |
303 | * This one can be called for an ongoing RPC request, and can be used in | 306 | * This one can be called for an ongoing RPC request, and can be used in |
304 | * an async (rpciod) context. | 307 | * an async (rpciod) context. |
305 | */ | 308 | */ |
306 | void rpcb_getport(struct rpc_task *task) | 309 | void rpcb_getport_async(struct rpc_task *task) |
307 | { | 310 | { |
308 | struct rpc_clnt *clnt = task->tk_client; | 311 | struct rpc_clnt *clnt = task->tk_client; |
309 | int bind_version; | 312 | int bind_version; |
@@ -314,17 +317,17 @@ void rpcb_getport(struct rpc_task *task) | |||
314 | struct sockaddr addr; | 317 | struct sockaddr addr; |
315 | int status; | 318 | int status; |
316 | 319 | ||
317 | dprintk("RPC: %5u rpcb_getport(%s, %u, %u, %d)\n", | 320 | dprintk("RPC: %5u %s(%s, %u, %u, %d)\n", |
318 | task->tk_pid, clnt->cl_server, | 321 | task->tk_pid, __FUNCTION__, |
319 | clnt->cl_prog, clnt->cl_vers, xprt->prot); | 322 | clnt->cl_server, clnt->cl_prog, clnt->cl_vers, xprt->prot); |
320 | 323 | ||
321 | /* Autobind on cloned rpc clients is discouraged */ | 324 | /* Autobind on cloned rpc clients is discouraged */ |
322 | BUG_ON(clnt->cl_parent != clnt); | 325 | BUG_ON(clnt->cl_parent != clnt); |
323 | 326 | ||
324 | if (xprt_test_and_set_binding(xprt)) { | 327 | if (xprt_test_and_set_binding(xprt)) { |
325 | status = -EACCES; /* tell caller to check again */ | 328 | status = -EACCES; /* tell caller to check again */ |
326 | dprintk("RPC: %5u rpcb_getport waiting for another binder\n", | 329 | dprintk("RPC: %5u %s: waiting for another binder\n", |
327 | task->tk_pid); | 330 | task->tk_pid, __FUNCTION__); |
328 | goto bailout_nowake; | 331 | goto bailout_nowake; |
329 | } | 332 | } |
330 | 333 | ||
@@ -335,27 +338,28 @@ void rpcb_getport(struct rpc_task *task) | |||
335 | /* Someone else may have bound if we slept */ | 338 | /* Someone else may have bound if we slept */ |
336 | if (xprt_bound(xprt)) { | 339 | if (xprt_bound(xprt)) { |
337 | status = 0; | 340 | status = 0; |
338 | dprintk("RPC: %5u rpcb_getport already bound\n", task->tk_pid); | 341 | dprintk("RPC: %5u %s: already bound\n", |
342 | task->tk_pid, __FUNCTION__); | ||
339 | goto bailout_nofree; | 343 | goto bailout_nofree; |
340 | } | 344 | } |
341 | 345 | ||
342 | if (rpcb_next_version[xprt->bind_index].rpc_proc == NULL) { | 346 | if (rpcb_next_version[xprt->bind_index].rpc_proc == NULL) { |
343 | xprt->bind_index = 0; | 347 | xprt->bind_index = 0; |
344 | status = -EACCES; /* tell caller to try again later */ | 348 | status = -EACCES; /* tell caller to try again later */ |
345 | dprintk("RPC: %5u rpcb_getport no more getport versions " | 349 | dprintk("RPC: %5u %s: no more getport versions available\n", |
346 | "available\n", task->tk_pid); | 350 | task->tk_pid, __FUNCTION__); |
347 | goto bailout_nofree; | 351 | goto bailout_nofree; |
348 | } | 352 | } |
349 | bind_version = rpcb_next_version[xprt->bind_index].rpc_vers; | 353 | bind_version = rpcb_next_version[xprt->bind_index].rpc_vers; |
350 | 354 | ||
351 | dprintk("RPC: %5u rpcb_getport trying rpcbind version %u\n", | 355 | dprintk("RPC: %5u %s: trying rpcbind version %u\n", |
352 | task->tk_pid, bind_version); | 356 | task->tk_pid, __FUNCTION__, bind_version); |
353 | 357 | ||
354 | map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC); | 358 | map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC); |
355 | if (!map) { | 359 | if (!map) { |
356 | status = -ENOMEM; | 360 | status = -ENOMEM; |
357 | dprintk("RPC: %5u rpcb_getport no memory available\n", | 361 | dprintk("RPC: %5u %s: no memory available\n", |
358 | task->tk_pid); | 362 | task->tk_pid, __FUNCTION__); |
359 | goto bailout_nofree; | 363 | goto bailout_nofree; |
360 | } | 364 | } |
361 | map->r_prog = clnt->cl_prog; | 365 | map->r_prog = clnt->cl_prog; |
@@ -373,16 +377,17 @@ void rpcb_getport(struct rpc_task *task) | |||
373 | rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot, bind_version, 0); | 377 | rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot, bind_version, 0); |
374 | if (IS_ERR(rpcb_clnt)) { | 378 | if (IS_ERR(rpcb_clnt)) { |
375 | status = PTR_ERR(rpcb_clnt); | 379 | status = PTR_ERR(rpcb_clnt); |
376 | dprintk("RPC: %5u rpcb_getport rpcb_create failed, error %ld\n", | 380 | dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n", |
377 | task->tk_pid, PTR_ERR(rpcb_clnt)); | 381 | task->tk_pid, __FUNCTION__, PTR_ERR(rpcb_clnt)); |
378 | goto bailout; | 382 | goto bailout; |
379 | } | 383 | } |
380 | 384 | ||
381 | child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map); | 385 | child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map); |
386 | rpc_release_client(rpcb_clnt); | ||
382 | if (IS_ERR(child)) { | 387 | if (IS_ERR(child)) { |
383 | status = -EIO; | 388 | status = -EIO; |
384 | dprintk("RPC: %5u rpcb_getport rpc_run_task failed\n", | 389 | dprintk("RPC: %5u %s: rpc_run_task failed\n", |
385 | task->tk_pid); | 390 | task->tk_pid, __FUNCTION__); |
386 | goto bailout_nofree; | 391 | goto bailout_nofree; |
387 | } | 392 | } |
388 | rpc_put_task(child); | 393 | rpc_put_task(child); |