diff options
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r-- | net/sunrpc/clnt.c | 53 |
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 | ||
177 | out_no_auth: | 185 | out_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 | } | ||
179 | out_no_path: | 191 | out_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; |
249 | out_no_clnt: | 265 | out_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); |
316 | out_free: | 332 | out_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); |
499 | out: | 522 | return status; |
523 | out_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); |