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.c107
1 files changed, 60 insertions, 47 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 61c3abeaccae..5530ac8c6df9 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -374,19 +374,23 @@ out:
374 * Default callback for async RPC calls 374 * Default callback for async RPC calls
375 */ 375 */
376static void 376static void
377rpc_default_callback(struct rpc_task *task) 377rpc_default_callback(struct rpc_task *task, void *data)
378{ 378{
379} 379}
380 380
381static const struct rpc_call_ops rpc_default_ops = {
382 .rpc_call_done = rpc_default_callback,
383};
384
381/* 385/*
382 * Export the signal mask handling for synchronous code that 386 * Export the signal mask handling for synchronous code that
383 * sleeps on RPC calls 387 * sleeps on RPC calls
384 */ 388 */
385#define RPC_INTR_SIGNALS (sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGKILL)) 389#define RPC_INTR_SIGNALS (sigmask(SIGHUP) | sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGTERM))
386 390
387static void rpc_save_sigmask(sigset_t *oldset, int intr) 391static void rpc_save_sigmask(sigset_t *oldset, int intr)
388{ 392{
389 unsigned long sigallow = 0; 393 unsigned long sigallow = sigmask(SIGKILL);
390 sigset_t sigmask; 394 sigset_t sigmask;
391 395
392 /* Block all signals except those listed in sigallow */ 396 /* Block all signals except those listed in sigallow */
@@ -432,7 +436,7 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
432 BUG_ON(flags & RPC_TASK_ASYNC); 436 BUG_ON(flags & RPC_TASK_ASYNC);
433 437
434 status = -ENOMEM; 438 status = -ENOMEM;
435 task = rpc_new_task(clnt, NULL, flags); 439 task = rpc_new_task(clnt, flags, &rpc_default_ops, NULL);
436 if (task == NULL) 440 if (task == NULL)
437 goto out; 441 goto out;
438 442
@@ -442,14 +446,15 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
442 rpc_call_setup(task, msg, 0); 446 rpc_call_setup(task, msg, 0);
443 447
444 /* Set up the call info struct and execute the task */ 448 /* Set up the call info struct and execute the task */
445 if (task->tk_status == 0) { 449 status = task->tk_status;
450 if (status == 0) {
451 atomic_inc(&task->tk_count);
446 status = rpc_execute(task); 452 status = rpc_execute(task);
447 } else { 453 if (status == 0)
448 status = task->tk_status; 454 status = task->tk_status;
449 rpc_release_task(task);
450 } 455 }
451
452 rpc_restore_sigmask(&oldset); 456 rpc_restore_sigmask(&oldset);
457 rpc_release_task(task);
453out: 458out:
454 return status; 459 return status;
455} 460}
@@ -459,7 +464,7 @@ out:
459 */ 464 */
460int 465int
461rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags, 466rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
462 rpc_action callback, void *data) 467 const struct rpc_call_ops *tk_ops, void *data)
463{ 468{
464 struct rpc_task *task; 469 struct rpc_task *task;
465 sigset_t oldset; 470 sigset_t oldset;
@@ -472,12 +477,9 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
472 flags |= RPC_TASK_ASYNC; 477 flags |= RPC_TASK_ASYNC;
473 478
474 /* Create/initialize a new RPC task */ 479 /* Create/initialize a new RPC task */
475 if (!callback)
476 callback = rpc_default_callback;
477 status = -ENOMEM; 480 status = -ENOMEM;
478 if (!(task = rpc_new_task(clnt, callback, flags))) 481 if (!(task = rpc_new_task(clnt, flags, tk_ops, data)))
479 goto out; 482 goto out;
480 task->tk_calldata = data;
481 483
482 /* Mask signals on GSS_AUTH upcalls */ 484 /* Mask signals on GSS_AUTH upcalls */
483 rpc_task_sigmask(task, &oldset); 485 rpc_task_sigmask(task, &oldset);
@@ -511,7 +513,7 @@ rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags)
511 if (task->tk_status == 0) 513 if (task->tk_status == 0)
512 task->tk_action = call_start; 514 task->tk_action = call_start;
513 else 515 else
514 task->tk_action = NULL; 516 task->tk_action = rpc_exit_task;
515} 517}
516 518
517void 519void
@@ -536,6 +538,18 @@ size_t rpc_max_payload(struct rpc_clnt *clnt)
536} 538}
537EXPORT_SYMBOL(rpc_max_payload); 539EXPORT_SYMBOL(rpc_max_payload);
538 540
541/**
542 * rpc_force_rebind - force transport to check that remote port is unchanged
543 * @clnt: client to rebind
544 *
545 */
546void rpc_force_rebind(struct rpc_clnt *clnt)
547{
548 if (clnt->cl_autobind)
549 clnt->cl_port = 0;
550}
551EXPORT_SYMBOL(rpc_force_rebind);
552
539/* 553/*
540 * Restart an (async) RPC call. Usually called from within the 554 * Restart an (async) RPC call. Usually called from within the
541 * exit handler. 555 * exit handler.
@@ -642,24 +656,26 @@ call_reserveresult(struct rpc_task *task)
642 656
643/* 657/*
644 * 2. Allocate the buffer. For details, see sched.c:rpc_malloc. 658 * 2. Allocate the buffer. For details, see sched.c:rpc_malloc.
645 * (Note: buffer memory is freed in rpc_task_release). 659 * (Note: buffer memory is freed in xprt_release).
646 */ 660 */
647static void 661static void
648call_allocate(struct rpc_task *task) 662call_allocate(struct rpc_task *task)
649{ 663{
664 struct rpc_rqst *req = task->tk_rqstp;
665 struct rpc_xprt *xprt = task->tk_xprt;
650 unsigned int bufsiz; 666 unsigned int bufsiz;
651 667
652 dprintk("RPC: %4d call_allocate (status %d)\n", 668 dprintk("RPC: %4d call_allocate (status %d)\n",
653 task->tk_pid, task->tk_status); 669 task->tk_pid, task->tk_status);
654 task->tk_action = call_bind; 670 task->tk_action = call_bind;
655 if (task->tk_buffer) 671 if (req->rq_buffer)
656 return; 672 return;
657 673
658 /* FIXME: compute buffer requirements more exactly using 674 /* FIXME: compute buffer requirements more exactly using
659 * auth->au_wslack */ 675 * auth->au_wslack */
660 bufsiz = task->tk_msg.rpc_proc->p_bufsiz + RPC_SLACK_SPACE; 676 bufsiz = task->tk_msg.rpc_proc->p_bufsiz + RPC_SLACK_SPACE;
661 677
662 if (rpc_malloc(task, bufsiz << 1) != NULL) 678 if (xprt->ops->buf_alloc(task, bufsiz << 1) != NULL)
663 return; 679 return;
664 printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task); 680 printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task);
665 681
@@ -702,14 +718,14 @@ call_encode(struct rpc_task *task)
702 task->tk_pid, task->tk_status); 718 task->tk_pid, task->tk_status);
703 719
704 /* Default buffer setup */ 720 /* Default buffer setup */
705 bufsiz = task->tk_bufsize >> 1; 721 bufsiz = req->rq_bufsize >> 1;
706 sndbuf->head[0].iov_base = (void *)task->tk_buffer; 722 sndbuf->head[0].iov_base = (void *)req->rq_buffer;
707 sndbuf->head[0].iov_len = bufsiz; 723 sndbuf->head[0].iov_len = bufsiz;
708 sndbuf->tail[0].iov_len = 0; 724 sndbuf->tail[0].iov_len = 0;
709 sndbuf->page_len = 0; 725 sndbuf->page_len = 0;
710 sndbuf->len = 0; 726 sndbuf->len = 0;
711 sndbuf->buflen = bufsiz; 727 sndbuf->buflen = bufsiz;
712 rcvbuf->head[0].iov_base = (void *)((char *)task->tk_buffer + bufsiz); 728 rcvbuf->head[0].iov_base = (void *)((char *)req->rq_buffer + bufsiz);
713 rcvbuf->head[0].iov_len = bufsiz; 729 rcvbuf->head[0].iov_len = bufsiz;
714 rcvbuf->tail[0].iov_len = 0; 730 rcvbuf->tail[0].iov_len = 0;
715 rcvbuf->page_len = 0; 731 rcvbuf->page_len = 0;
@@ -849,8 +865,7 @@ call_connect_status(struct rpc_task *task)
849 } 865 }
850 866
851 /* Something failed: remote service port may have changed */ 867 /* Something failed: remote service port may have changed */
852 if (clnt->cl_autobind) 868 rpc_force_rebind(clnt);
853 clnt->cl_port = 0;
854 869
855 switch (status) { 870 switch (status) {
856 case -ENOTCONN: 871 case -ENOTCONN:
@@ -892,7 +907,7 @@ call_transmit(struct rpc_task *task)
892 if (task->tk_status < 0) 907 if (task->tk_status < 0)
893 return; 908 return;
894 if (!task->tk_msg.rpc_proc->p_decode) { 909 if (!task->tk_msg.rpc_proc->p_decode) {
895 task->tk_action = NULL; 910 task->tk_action = rpc_exit_task;
896 rpc_wake_up_task(task); 911 rpc_wake_up_task(task);
897 } 912 }
898 return; 913 return;
@@ -931,8 +946,7 @@ call_status(struct rpc_task *task)
931 break; 946 break;
932 case -ECONNREFUSED: 947 case -ECONNREFUSED:
933 case -ENOTCONN: 948 case -ENOTCONN:
934 if (clnt->cl_autobind) 949 rpc_force_rebind(clnt);
935 clnt->cl_port = 0;
936 task->tk_action = call_bind; 950 task->tk_action = call_bind;
937 break; 951 break;
938 case -EAGAIN: 952 case -EAGAIN:
@@ -943,8 +957,7 @@ call_status(struct rpc_task *task)
943 rpc_exit(task, status); 957 rpc_exit(task, status);
944 break; 958 break;
945 default: 959 default:
946 if (clnt->cl_chatty) 960 printk("%s: RPC call returned error %d\n",
947 printk("%s: RPC call returned error %d\n",
948 clnt->cl_protname, -status); 961 clnt->cl_protname, -status);
949 rpc_exit(task, status); 962 rpc_exit(task, status);
950 break; 963 break;
@@ -979,20 +992,18 @@ call_timeout(struct rpc_task *task)
979 992
980 dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid); 993 dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid);
981 if (RPC_IS_SOFT(task)) { 994 if (RPC_IS_SOFT(task)) {
982 if (clnt->cl_chatty) 995 printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
983 printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
984 clnt->cl_protname, clnt->cl_server); 996 clnt->cl_protname, clnt->cl_server);
985 rpc_exit(task, -EIO); 997 rpc_exit(task, -EIO);
986 return; 998 return;
987 } 999 }
988 1000
989 if (clnt->cl_chatty && !(task->tk_flags & RPC_CALL_MAJORSEEN)) { 1001 if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) {
990 task->tk_flags |= RPC_CALL_MAJORSEEN; 1002 task->tk_flags |= RPC_CALL_MAJORSEEN;
991 printk(KERN_NOTICE "%s: server %s not responding, still trying\n", 1003 printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
992 clnt->cl_protname, clnt->cl_server); 1004 clnt->cl_protname, clnt->cl_server);
993 } 1005 }
994 if (clnt->cl_autobind) 1006 rpc_force_rebind(clnt);
995 clnt->cl_port = 0;
996 1007
997retry: 1008retry:
998 clnt->cl_stats->rpcretrans++; 1009 clnt->cl_stats->rpcretrans++;
@@ -1014,7 +1025,7 @@ call_decode(struct rpc_task *task)
1014 dprintk("RPC: %4d call_decode (status %d)\n", 1025 dprintk("RPC: %4d call_decode (status %d)\n",
1015 task->tk_pid, task->tk_status); 1026 task->tk_pid, task->tk_status);
1016 1027
1017 if (clnt->cl_chatty && (task->tk_flags & RPC_CALL_MAJORSEEN)) { 1028 if (task->tk_flags & RPC_CALL_MAJORSEEN) {
1018 printk(KERN_NOTICE "%s: server %s OK\n", 1029 printk(KERN_NOTICE "%s: server %s OK\n",
1019 clnt->cl_protname, clnt->cl_server); 1030 clnt->cl_protname, clnt->cl_server);
1020 task->tk_flags &= ~RPC_CALL_MAJORSEEN; 1031 task->tk_flags &= ~RPC_CALL_MAJORSEEN;
@@ -1039,13 +1050,14 @@ call_decode(struct rpc_task *task)
1039 sizeof(req->rq_rcv_buf)) != 0); 1050 sizeof(req->rq_rcv_buf)) != 0);
1040 1051
1041 /* Verify the RPC header */ 1052 /* Verify the RPC header */
1042 if (!(p = call_verify(task))) { 1053 p = call_verify(task);
1043 if (task->tk_action == NULL) 1054 if (IS_ERR(p)) {
1044 return; 1055 if (p == ERR_PTR(-EAGAIN))
1045 goto out_retry; 1056 goto out_retry;
1057 return;
1046 } 1058 }
1047 1059
1048 task->tk_action = NULL; 1060 task->tk_action = rpc_exit_task;
1049 1061
1050 if (decode) 1062 if (decode)
1051 task->tk_status = rpcauth_unwrap_resp(task, decode, req, p, 1063 task->tk_status = rpcauth_unwrap_resp(task, decode, req, p,
@@ -1138,7 +1150,7 @@ call_verify(struct rpc_task *task)
1138 1150
1139 if ((n = ntohl(*p++)) != RPC_REPLY) { 1151 if ((n = ntohl(*p++)) != RPC_REPLY) {
1140 printk(KERN_WARNING "call_verify: not an RPC reply: %x\n", n); 1152 printk(KERN_WARNING "call_verify: not an RPC reply: %x\n", n);
1141 goto out_retry; 1153 goto out_garbage;
1142 } 1154 }
1143 if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) { 1155 if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
1144 if (--len < 0) 1156 if (--len < 0)
@@ -1168,7 +1180,7 @@ call_verify(struct rpc_task *task)
1168 task->tk_pid); 1180 task->tk_pid);
1169 rpcauth_invalcred(task); 1181 rpcauth_invalcred(task);
1170 task->tk_action = call_refresh; 1182 task->tk_action = call_refresh;
1171 return NULL; 1183 goto out_retry;
1172 case RPC_AUTH_BADCRED: 1184 case RPC_AUTH_BADCRED:
1173 case RPC_AUTH_BADVERF: 1185 case RPC_AUTH_BADVERF:
1174 /* possibly garbled cred/verf? */ 1186 /* possibly garbled cred/verf? */
@@ -1178,7 +1190,7 @@ call_verify(struct rpc_task *task)
1178 dprintk("RPC: %4d call_verify: retry garbled creds\n", 1190 dprintk("RPC: %4d call_verify: retry garbled creds\n",
1179 task->tk_pid); 1191 task->tk_pid);
1180 task->tk_action = call_bind; 1192 task->tk_action = call_bind;
1181 return NULL; 1193 goto out_retry;
1182 case RPC_AUTH_TOOWEAK: 1194 case RPC_AUTH_TOOWEAK:
1183 printk(KERN_NOTICE "call_verify: server requires stronger " 1195 printk(KERN_NOTICE "call_verify: server requires stronger "
1184 "authentication.\n"); 1196 "authentication.\n");
@@ -1193,7 +1205,7 @@ call_verify(struct rpc_task *task)
1193 } 1205 }
1194 if (!(p = rpcauth_checkverf(task, p))) { 1206 if (!(p = rpcauth_checkverf(task, p))) {
1195 printk(KERN_WARNING "call_verify: auth check failed\n"); 1207 printk(KERN_WARNING "call_verify: auth check failed\n");
1196 goto out_retry; /* bad verifier, retry */ 1208 goto out_garbage; /* bad verifier, retry */
1197 } 1209 }
1198 len = p - (u32 *)iov->iov_base - 1; 1210 len = p - (u32 *)iov->iov_base - 1;
1199 if (len < 0) 1211 if (len < 0)
@@ -1230,23 +1242,24 @@ call_verify(struct rpc_task *task)
1230 /* Also retry */ 1242 /* Also retry */
1231 } 1243 }
1232 1244
1233out_retry: 1245out_garbage:
1234 task->tk_client->cl_stats->rpcgarbage++; 1246 task->tk_client->cl_stats->rpcgarbage++;
1235 if (task->tk_garb_retry) { 1247 if (task->tk_garb_retry) {
1236 task->tk_garb_retry--; 1248 task->tk_garb_retry--;
1237 dprintk("RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid); 1249 dprintk("RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid);
1238 task->tk_action = call_bind; 1250 task->tk_action = call_bind;
1239 return NULL; 1251out_retry:
1252 return ERR_PTR(-EAGAIN);
1240 } 1253 }
1241 printk(KERN_WARNING "RPC %s: retry failed, exit EIO\n", __FUNCTION__); 1254 printk(KERN_WARNING "RPC %s: retry failed, exit EIO\n", __FUNCTION__);
1242out_eio: 1255out_eio:
1243 error = -EIO; 1256 error = -EIO;
1244out_err: 1257out_err:
1245 rpc_exit(task, error); 1258 rpc_exit(task, error);
1246 return NULL; 1259 return ERR_PTR(error);
1247out_overflow: 1260out_overflow:
1248 printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__); 1261 printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__);
1249 goto out_retry; 1262 goto out_garbage;
1250} 1263}
1251 1264
1252static int rpcproc_encode_null(void *rqstp, u32 *data, void *obj) 1265static int rpcproc_encode_null(void *rqstp, u32 *data, void *obj)