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.c56
1 files changed, 45 insertions, 11 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index d2f0550c4ba0..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 }
@@ -113,7 +120,7 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname,
113 120
114 err = -EINVAL; 121 err = -EINVAL;
115 if (!xprt) 122 if (!xprt)
116 goto out_err; 123 goto out_no_xprt;
117 if (vers >= program->nrvers || !(version = program->version[vers])) 124 if (vers >= program->nrvers || !(version = program->version[vers]))
118 goto out_err; 125 goto out_err;
119 126
@@ -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,13 +183,18 @@ 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);
182 kfree(clnt); 194 kfree(clnt);
183out_err: 195out_err:
184 xprt_destroy(xprt); 196 xprt_destroy(xprt);
197out_no_xprt:
185 return ERR_PTR(err); 198 return ERR_PTR(err);
186} 199}
187 200
@@ -239,11 +252,15 @@ rpc_clone_client(struct rpc_clnt *clnt)
239 new->cl_autobind = 0; 252 new->cl_autobind = 0;
240 new->cl_oneshot = 0; 253 new->cl_oneshot = 0;
241 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 }
242 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);
243 if (new->cl_auth) 260 if (new->cl_auth)
244 atomic_inc(&new->cl_auth->au_count); 261 atomic_inc(&new->cl_auth->au_count);
245 new->cl_pmap = &new->cl_pmap_default; 262 new->cl_pmap = &new->cl_pmap_default;
246 rpc_init_wait_queue(&new->cl_pmap_default.pm_bindwait, "bindwait"); 263 new->cl_metrics = rpc_alloc_iostats(clnt);
247 return new; 264 return new;
248out_no_clnt: 265out_no_clnt:
249 printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__); 266 printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__);
@@ -313,6 +330,12 @@ rpc_destroy_client(struct rpc_clnt *clnt)
313 if (clnt->cl_server != clnt->cl_inline_name) 330 if (clnt->cl_server != clnt->cl_inline_name)
314 kfree(clnt->cl_server); 331 kfree(clnt->cl_server);
315out_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 }
316 kfree(clnt); 339 kfree(clnt);
317 return 0; 340 return 0;
318} 341}
@@ -472,15 +495,16 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
472 int status; 495 int status;
473 496
474 /* If this client is slain all further I/O fails */ 497 /* If this client is slain all further I/O fails */
498 status = -EIO;
475 if (clnt->cl_dead) 499 if (clnt->cl_dead)
476 return -EIO; 500 goto out_release;
477 501
478 flags |= RPC_TASK_ASYNC; 502 flags |= RPC_TASK_ASYNC;
479 503
480 /* Create/initialize a new RPC task */ 504 /* Create/initialize a new RPC task */
481 status = -ENOMEM; 505 status = -ENOMEM;
482 if (!(task = rpc_new_task(clnt, flags, tk_ops, data))) 506 if (!(task = rpc_new_task(clnt, flags, tk_ops, data)))
483 goto out; 507 goto out_release;
484 508
485 /* Mask signals on GSS_AUTH upcalls */ 509 /* Mask signals on GSS_AUTH upcalls */
486 rpc_task_sigmask(task, &oldset); 510 rpc_task_sigmask(task, &oldset);
@@ -495,7 +519,10 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
495 rpc_release_task(task); 519 rpc_release_task(task);
496 520
497 rpc_restore_sigmask(&oldset); 521 rpc_restore_sigmask(&oldset);
498out: 522 return status;
523out_release:
524 if (tk_ops->rpc_release != NULL)
525 tk_ops->rpc_release(data);
499 return status; 526 return status;
500} 527}
501 528
@@ -992,6 +1019,8 @@ call_timeout(struct rpc_task *task)
992 } 1019 }
993 1020
994 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
995 if (RPC_IS_SOFT(task)) { 1024 if (RPC_IS_SOFT(task)) {
996 printk(KERN_NOTICE "%s: server %s not responding, timed out\n", 1025 printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
997 clnt->cl_protname, clnt->cl_server); 1026 clnt->cl_protname, clnt->cl_server);
@@ -1044,6 +1073,11 @@ call_decode(struct rpc_task *task)
1044 return; 1073 return;
1045 } 1074 }
1046 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();
1047 req->rq_rcv_buf.len = req->rq_private_buf.len; 1081 req->rq_rcv_buf.len = req->rq_private_buf.len;
1048 1082
1049 /* Check that the softirq receive buffer is valid */ 1083 /* Check that the softirq receive buffer is valid */
@@ -1193,8 +1227,8 @@ call_verify(struct rpc_task *task)
1193 task->tk_action = call_bind; 1227 task->tk_action = call_bind;
1194 goto out_retry; 1228 goto out_retry;
1195 case RPC_AUTH_TOOWEAK: 1229 case RPC_AUTH_TOOWEAK:
1196 printk(KERN_NOTICE "call_verify: server requires stronger " 1230 printk(KERN_NOTICE "call_verify: server %s requires stronger "
1197 "authentication.\n"); 1231 "authentication.\n", task->tk_client->cl_server);
1198 break; 1232 break;
1199 default: 1233 default:
1200 printk(KERN_WARNING "call_verify: unknown auth error: %x\n", n); 1234 printk(KERN_WARNING "call_verify: unknown auth error: %x\n", n);