aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/clnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r--net/sunrpc/clnt.c70
1 files changed, 46 insertions, 24 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index dfeea4fea95a..aba528b9ae76 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -27,6 +27,7 @@
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/smp_lock.h>
30#include <linux/utsname.h> 31#include <linux/utsname.h>
31#include <linux/workqueue.h> 32#include <linux/workqueue.h>
32 33
@@ -141,6 +142,10 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
141 clnt->cl_vers = version->number; 142 clnt->cl_vers = version->number;
142 clnt->cl_stats = program->stats; 143 clnt->cl_stats = program->stats;
143 clnt->cl_metrics = rpc_alloc_iostats(clnt); 144 clnt->cl_metrics = rpc_alloc_iostats(clnt);
145 err = -ENOMEM;
146 if (clnt->cl_metrics == NULL)
147 goto out_no_stats;
148 clnt->cl_program = program;
144 149
145 if (!xprt_bound(clnt->cl_xprt)) 150 if (!xprt_bound(clnt->cl_xprt))
146 clnt->cl_autobind = 1; 151 clnt->cl_autobind = 1;
@@ -173,6 +178,8 @@ out_no_auth:
173 rpc_put_mount(); 178 rpc_put_mount();
174 } 179 }
175out_no_path: 180out_no_path:
181 rpc_free_iostats(clnt->cl_metrics);
182out_no_stats:
176 if (clnt->cl_server != clnt->cl_inline_name) 183 if (clnt->cl_server != clnt->cl_inline_name)
177 kfree(clnt->cl_server); 184 kfree(clnt->cl_server);
178 kfree(clnt); 185 kfree(clnt);
@@ -252,12 +259,19 @@ struct rpc_clnt *
252rpc_clone_client(struct rpc_clnt *clnt) 259rpc_clone_client(struct rpc_clnt *clnt)
253{ 260{
254 struct rpc_clnt *new; 261 struct rpc_clnt *new;
262 int err = -ENOMEM;
255 263
256 new = kmemdup(clnt, sizeof(*new), GFP_KERNEL); 264 new = kmemdup(clnt, sizeof(*new), GFP_KERNEL);
257 if (!new) 265 if (!new)
258 goto out_no_clnt; 266 goto out_no_clnt;
259 atomic_set(&new->cl_count, 1); 267 atomic_set(&new->cl_count, 1);
260 atomic_set(&new->cl_users, 0); 268 atomic_set(&new->cl_users, 0);
269 new->cl_metrics = rpc_alloc_iostats(clnt);
270 if (new->cl_metrics == NULL)
271 goto out_no_stats;
272 err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
273 if (err != 0)
274 goto out_no_path;
261 new->cl_parent = clnt; 275 new->cl_parent = clnt;
262 atomic_inc(&clnt->cl_count); 276 atomic_inc(&clnt->cl_count);
263 new->cl_xprt = xprt_get(clnt->cl_xprt); 277 new->cl_xprt = xprt_get(clnt->cl_xprt);
@@ -265,16 +279,17 @@ rpc_clone_client(struct rpc_clnt *clnt)
265 new->cl_autobind = 0; 279 new->cl_autobind = 0;
266 new->cl_oneshot = 0; 280 new->cl_oneshot = 0;
267 new->cl_dead = 0; 281 new->cl_dead = 0;
268 if (!IS_ERR(new->cl_dentry))
269 dget(new->cl_dentry);
270 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); 282 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
271 if (new->cl_auth) 283 if (new->cl_auth)
272 atomic_inc(&new->cl_auth->au_count); 284 atomic_inc(&new->cl_auth->au_count);
273 new->cl_metrics = rpc_alloc_iostats(clnt);
274 return new; 285 return new;
286out_no_path:
287 rpc_free_iostats(new->cl_metrics);
288out_no_stats:
289 kfree(new);
275out_no_clnt: 290out_no_clnt:
276 printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__); 291 dprintk("RPC: %s returned error %d\n", __FUNCTION__, err);
277 return ERR_PTR(-ENOMEM); 292 return ERR_PTR(err);
278} 293}
279 294
280/* 295/*
@@ -327,16 +342,14 @@ rpc_destroy_client(struct rpc_clnt *clnt)
327 rpcauth_destroy(clnt->cl_auth); 342 rpcauth_destroy(clnt->cl_auth);
328 clnt->cl_auth = NULL; 343 clnt->cl_auth = NULL;
329 } 344 }
330 if (clnt->cl_parent != clnt) {
331 if (!IS_ERR(clnt->cl_dentry))
332 dput(clnt->cl_dentry);
333 rpc_destroy_client(clnt->cl_parent);
334 goto out_free;
335 }
336 if (!IS_ERR(clnt->cl_dentry)) { 345 if (!IS_ERR(clnt->cl_dentry)) {
337 rpc_rmdir(clnt->cl_dentry); 346 rpc_rmdir(clnt->cl_dentry);
338 rpc_put_mount(); 347 rpc_put_mount();
339 } 348 }
349 if (clnt->cl_parent != clnt) {
350 rpc_destroy_client(clnt->cl_parent);
351 goto out_free;
352 }
340 if (clnt->cl_server != clnt->cl_inline_name) 353 if (clnt->cl_server != clnt->cl_inline_name)
341 kfree(clnt->cl_server); 354 kfree(clnt->cl_server);
342out_free: 355out_free:
@@ -466,10 +479,9 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
466 479
467 BUG_ON(flags & RPC_TASK_ASYNC); 480 BUG_ON(flags & RPC_TASK_ASYNC);
468 481
469 status = -ENOMEM;
470 task = rpc_new_task(clnt, flags, &rpc_default_ops, NULL); 482 task = rpc_new_task(clnt, flags, &rpc_default_ops, NULL);
471 if (task == NULL) 483 if (task == NULL)
472 goto out; 484 return -ENOMEM;
473 485
474 /* Mask signals on RPC calls _and_ GSS_AUTH upcalls */ 486 /* Mask signals on RPC calls _and_ GSS_AUTH upcalls */
475 rpc_task_sigmask(task, &oldset); 487 rpc_task_sigmask(task, &oldset);
@@ -478,15 +490,17 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
478 490
479 /* Set up the call info struct and execute the task */ 491 /* Set up the call info struct and execute the task */
480 status = task->tk_status; 492 status = task->tk_status;
481 if (status == 0) { 493 if (status != 0) {
482 atomic_inc(&task->tk_count); 494 rpc_release_task(task);
483 status = rpc_execute(task); 495 goto out;
484 if (status == 0)
485 status = task->tk_status;
486 } 496 }
487 rpc_restore_sigmask(&oldset); 497 atomic_inc(&task->tk_count);
488 rpc_release_task(task); 498 status = rpc_execute(task);
499 if (status == 0)
500 status = task->tk_status;
501 rpc_put_task(task);
489out: 502out:
503 rpc_restore_sigmask(&oldset);
490 return status; 504 return status;
491} 505}
492 506
@@ -528,8 +542,7 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
528 rpc_restore_sigmask(&oldset); 542 rpc_restore_sigmask(&oldset);
529 return status; 543 return status;
530out_release: 544out_release:
531 if (tk_ops->rpc_release != NULL) 545 rpc_release_calldata(tk_ops, data);
532 tk_ops->rpc_release(data);
533 return status; 546 return status;
534} 547}
535 548
@@ -581,7 +594,11 @@ EXPORT_SYMBOL_GPL(rpc_peeraddr);
581char *rpc_peeraddr2str(struct rpc_clnt *clnt, enum rpc_display_format_t format) 594char *rpc_peeraddr2str(struct rpc_clnt *clnt, enum rpc_display_format_t format)
582{ 595{
583 struct rpc_xprt *xprt = clnt->cl_xprt; 596 struct rpc_xprt *xprt = clnt->cl_xprt;
584 return xprt->ops->print_addr(xprt, format); 597
598 if (xprt->address_strings[format] != NULL)
599 return xprt->address_strings[format];
600 else
601 return "unprintable";
585} 602}
586EXPORT_SYMBOL_GPL(rpc_peeraddr2str); 603EXPORT_SYMBOL_GPL(rpc_peeraddr2str);
587 604
@@ -811,8 +828,10 @@ call_encode(struct rpc_task *task)
811 if (encode == NULL) 828 if (encode == NULL)
812 return; 829 return;
813 830
831 lock_kernel();
814 task->tk_status = rpcauth_wrap_req(task, encode, req, p, 832 task->tk_status = rpcauth_wrap_req(task, encode, req, p,
815 task->tk_msg.rpc_argp); 833 task->tk_msg.rpc_argp);
834 unlock_kernel();
816 if (task->tk_status == -ENOMEM) { 835 if (task->tk_status == -ENOMEM) {
817 /* XXX: Is this sane? */ 836 /* XXX: Is this sane? */
818 rpc_delay(task, 3*HZ); 837 rpc_delay(task, 3*HZ);
@@ -1143,9 +1162,12 @@ call_decode(struct rpc_task *task)
1143 1162
1144 task->tk_action = rpc_exit_task; 1163 task->tk_action = rpc_exit_task;
1145 1164
1146 if (decode) 1165 if (decode) {
1166 lock_kernel();
1147 task->tk_status = rpcauth_unwrap_resp(task, decode, req, p, 1167 task->tk_status = rpcauth_unwrap_resp(task, decode, req, p,
1148 task->tk_msg.rpc_resp); 1168 task->tk_msg.rpc_resp);
1169 unlock_kernel();
1170 }
1149 dprintk("RPC: %4d call_decode result %d\n", task->tk_pid, 1171 dprintk("RPC: %4d call_decode result %d\n", task->tk_pid,
1150 task->tk_status); 1172 task->tk_status);
1151 return; 1173 return;