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.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index d78479782045..aa8965e9d307 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -28,12 +28,11 @@
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/utsname.h> 30#include <linux/utsname.h>
31#include <linux/workqueue.h>
31 32
32#include <linux/sunrpc/clnt.h> 33#include <linux/sunrpc/clnt.h>
33#include <linux/workqueue.h>
34#include <linux/sunrpc/rpc_pipe_fs.h> 34#include <linux/sunrpc/rpc_pipe_fs.h>
35 35#include <linux/sunrpc/metrics.h>
36#include <linux/nfs.h>
37 36
38 37
39#define RPC_SLACK_SPACE (1024) /* total overkill */ 38#define RPC_SLACK_SPACE (1024) /* total overkill */
@@ -71,8 +70,15 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
71 static uint32_t clntid; 70 static uint32_t clntid;
72 int error; 71 int error;
73 72
73 clnt->cl_vfsmnt = ERR_PTR(-ENOENT);
74 clnt->cl_dentry = ERR_PTR(-ENOENT);
74 if (dir_name == NULL) 75 if (dir_name == NULL)
75 return 0; 76 return 0;
77
78 clnt->cl_vfsmnt = rpc_get_mount();
79 if (IS_ERR(clnt->cl_vfsmnt))
80 return PTR_ERR(clnt->cl_vfsmnt);
81
76 for (;;) { 82 for (;;) {
77 snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname), 83 snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname),
78 "%s/clnt%x", dir_name, 84 "%s/clnt%x", dir_name,
@@ -85,6 +91,7 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
85 if (error != -EEXIST) { 91 if (error != -EEXIST) {
86 printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n", 92 printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n",
87 clnt->cl_pathname, error); 93 clnt->cl_pathname, error);
94 rpc_put_mount();
88 return error; 95 return error;
89 } 96 }
90 } 97 }
@@ -147,6 +154,7 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname,
147 clnt->cl_vers = version->number; 154 clnt->cl_vers = version->number;
148 clnt->cl_prot = xprt->prot; 155 clnt->cl_prot = xprt->prot;
149 clnt->cl_stats = program->stats; 156 clnt->cl_stats = program->stats;
157 clnt->cl_metrics = rpc_alloc_iostats(clnt);
150 rpc_init_wait_queue(&clnt->cl_pmap_default.pm_bindwait, "bindwait"); 158 rpc_init_wait_queue(&clnt->cl_pmap_default.pm_bindwait, "bindwait");
151 159
152 if (!clnt->cl_port) 160 if (!clnt->cl_port)
@@ -175,7 +183,11 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname,
175 return clnt; 183 return clnt;
176 184
177out_no_auth: 185out_no_auth:
178 rpc_rmdir(clnt->cl_pathname); 186 if (!IS_ERR(clnt->cl_dentry)) {
187 rpc_rmdir(clnt->cl_pathname);
188 dput(clnt->cl_dentry);
189 rpc_put_mount();
190 }
179out_no_path: 191out_no_path:
180 if (clnt->cl_server != clnt->cl_inline_name) 192 if (clnt->cl_server != clnt->cl_inline_name)
181 kfree(clnt->cl_server); 193 kfree(clnt->cl_server);
@@ -240,11 +252,15 @@ rpc_clone_client(struct rpc_clnt *clnt)
240 new->cl_autobind = 0; 252 new->cl_autobind = 0;
241 new->cl_oneshot = 0; 253 new->cl_oneshot = 0;
242 new->cl_dead = 0; 254 new->cl_dead = 0;
255 if (!IS_ERR(new->cl_dentry)) {
256 dget(new->cl_dentry);
257 rpc_get_mount();
258 }
243 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); 259 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
244 if (new->cl_auth) 260 if (new->cl_auth)
245 atomic_inc(&new->cl_auth->au_count); 261 atomic_inc(&new->cl_auth->au_count);
246 new->cl_pmap = &new->cl_pmap_default; 262 new->cl_pmap = &new->cl_pmap_default;
247 rpc_init_wait_queue(&new->cl_pmap_default.pm_bindwait, "bindwait"); 263 new->cl_metrics = rpc_alloc_iostats(clnt);
248 return new; 264 return new;
249out_no_clnt: 265out_no_clnt:
250 printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__); 266 printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__);
@@ -314,6 +330,12 @@ rpc_destroy_client(struct rpc_clnt *clnt)
314 if (clnt->cl_server != clnt->cl_inline_name) 330 if (clnt->cl_server != clnt->cl_inline_name)
315 kfree(clnt->cl_server); 331 kfree(clnt->cl_server);
316out_free: 332out_free:
333 rpc_free_iostats(clnt->cl_metrics);
334 clnt->cl_metrics = NULL;
335 if (!IS_ERR(clnt->cl_dentry)) {
336 dput(clnt->cl_dentry);
337 rpc_put_mount();
338 }
317 kfree(clnt); 339 kfree(clnt);
318 return 0; 340 return 0;
319} 341}
@@ -473,15 +495,16 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
473 int status; 495 int status;
474 496
475 /* If this client is slain all further I/O fails */ 497 /* If this client is slain all further I/O fails */
498 status = -EIO;
476 if (clnt->cl_dead) 499 if (clnt->cl_dead)
477 return -EIO; 500 goto out_release;
478 501
479 flags |= RPC_TASK_ASYNC; 502 flags |= RPC_TASK_ASYNC;
480 503
481 /* Create/initialize a new RPC task */ 504 /* Create/initialize a new RPC task */
482 status = -ENOMEM; 505 status = -ENOMEM;
483 if (!(task = rpc_new_task(clnt, flags, tk_ops, data))) 506 if (!(task = rpc_new_task(clnt, flags, tk_ops, data)))
484 goto out; 507 goto out_release;
485 508
486 /* Mask signals on GSS_AUTH upcalls */ 509 /* Mask signals on GSS_AUTH upcalls */
487 rpc_task_sigmask(task, &oldset); 510 rpc_task_sigmask(task, &oldset);
@@ -496,7 +519,10 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
496 rpc_release_task(task); 519 rpc_release_task(task);
497 520
498 rpc_restore_sigmask(&oldset); 521 rpc_restore_sigmask(&oldset);
499out: 522 return status;
523out_release:
524 if (tk_ops->rpc_release != NULL)
525 tk_ops->rpc_release(data);
500 return status; 526 return status;
501} 527}
502 528
@@ -993,6 +1019,8 @@ call_timeout(struct rpc_task *task)
993 } 1019 }
994 1020
995 dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid); 1021 dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid);
1022 task->tk_timeouts++;
1023
996 if (RPC_IS_SOFT(task)) { 1024 if (RPC_IS_SOFT(task)) {
997 printk(KERN_NOTICE "%s: server %s not responding, timed out\n", 1025 printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
998 clnt->cl_protname, clnt->cl_server); 1026 clnt->cl_protname, clnt->cl_server);
@@ -1045,6 +1073,11 @@ call_decode(struct rpc_task *task)
1045 return; 1073 return;
1046 } 1074 }
1047 1075
1076 /*
1077 * Ensure that we see all writes made by xprt_complete_rqst()
1078 * before it changed req->rq_received.
1079 */
1080 smp_rmb();
1048 req->rq_rcv_buf.len = req->rq_private_buf.len; 1081 req->rq_rcv_buf.len = req->rq_private_buf.len;
1049 1082
1050 /* Check that the softirq receive buffer is valid */ 1083 /* Check that the softirq receive buffer is valid */
@@ -1194,8 +1227,8 @@ call_verify(struct rpc_task *task)
1194 task->tk_action = call_bind; 1227 task->tk_action = call_bind;
1195 goto out_retry; 1228 goto out_retry;
1196 case RPC_AUTH_TOOWEAK: 1229 case RPC_AUTH_TOOWEAK:
1197 printk(KERN_NOTICE "call_verify: server requires stronger " 1230 printk(KERN_NOTICE "call_verify: server %s requires stronger "
1198 "authentication.\n"); 1231 "authentication.\n", task->tk_client->cl_server);
1199 break; 1232 break;
1200 default: 1233 default:
1201 printk(KERN_WARNING "call_verify: unknown auth error: %x\n", n); 1234 printk(KERN_WARNING "call_verify: unknown auth error: %x\n", n);