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.c55
1 files changed, 47 insertions, 8 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 38829e20500b..19c9983d5360 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -79,7 +79,7 @@ static void call_connect_status(struct rpc_task *task);
79 79
80static __be32 *rpc_encode_header(struct rpc_task *task); 80static __be32 *rpc_encode_header(struct rpc_task *task);
81static __be32 *rpc_verify_header(struct rpc_task *task); 81static __be32 *rpc_verify_header(struct rpc_task *task);
82static int rpc_ping(struct rpc_clnt *clnt, int flags); 82static int rpc_ping(struct rpc_clnt *clnt);
83 83
84static void rpc_register_client(struct rpc_clnt *clnt) 84static void rpc_register_client(struct rpc_clnt *clnt)
85{ 85{
@@ -340,7 +340,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
340 return clnt; 340 return clnt;
341 341
342 if (!(args->flags & RPC_CLNT_CREATE_NOPING)) { 342 if (!(args->flags & RPC_CLNT_CREATE_NOPING)) {
343 int err = rpc_ping(clnt, RPC_TASK_SOFT); 343 int err = rpc_ping(clnt);
344 if (err != 0) { 344 if (err != 0) {
345 rpc_shutdown_client(clnt); 345 rpc_shutdown_client(clnt);
346 return ERR_PTR(err); 346 return ERR_PTR(err);
@@ -528,7 +528,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
528 clnt->cl_prog = program->number; 528 clnt->cl_prog = program->number;
529 clnt->cl_vers = version->number; 529 clnt->cl_vers = version->number;
530 clnt->cl_stats = program->stats; 530 clnt->cl_stats = program->stats;
531 err = rpc_ping(clnt, RPC_TASK_SOFT); 531 err = rpc_ping(clnt);
532 if (err != 0) { 532 if (err != 0) {
533 rpc_shutdown_client(clnt); 533 rpc_shutdown_client(clnt);
534 clnt = ERR_PTR(err); 534 clnt = ERR_PTR(err);
@@ -659,6 +659,7 @@ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req,
659 task = rpc_new_task(&task_setup_data); 659 task = rpc_new_task(&task_setup_data);
660 if (!task) { 660 if (!task) {
661 xprt_free_bc_request(req); 661 xprt_free_bc_request(req);
662 task = ERR_PTR(-ENOMEM);
662 goto out; 663 goto out;
663 } 664 }
664 task->tk_rqstp = req; 665 task->tk_rqstp = req;
@@ -1060,7 +1061,7 @@ call_bind_status(struct rpc_task *task)
1060 goto retry_timeout; 1061 goto retry_timeout;
1061 case -EPFNOSUPPORT: 1062 case -EPFNOSUPPORT:
1062 /* server doesn't support any rpcbind version we know of */ 1063 /* server doesn't support any rpcbind version we know of */
1063 dprintk("RPC: %5u remote rpcbind service unavailable\n", 1064 dprintk("RPC: %5u unrecognized remote rpcbind service\n",
1064 task->tk_pid); 1065 task->tk_pid);
1065 break; 1066 break;
1066 case -EPROTONOSUPPORT: 1067 case -EPROTONOSUPPORT:
@@ -1069,6 +1070,21 @@ call_bind_status(struct rpc_task *task)
1069 task->tk_status = 0; 1070 task->tk_status = 0;
1070 task->tk_action = call_bind; 1071 task->tk_action = call_bind;
1071 return; 1072 return;
1073 case -ECONNREFUSED: /* connection problems */
1074 case -ECONNRESET:
1075 case -ENOTCONN:
1076 case -EHOSTDOWN:
1077 case -EHOSTUNREACH:
1078 case -ENETUNREACH:
1079 case -EPIPE:
1080 dprintk("RPC: %5u remote rpcbind unreachable: %d\n",
1081 task->tk_pid, task->tk_status);
1082 if (!RPC_IS_SOFTCONN(task)) {
1083 rpc_delay(task, 5*HZ);
1084 goto retry_timeout;
1085 }
1086 status = task->tk_status;
1087 break;
1072 default: 1088 default:
1073 dprintk("RPC: %5u unrecognized rpcbind error (%d)\n", 1089 dprintk("RPC: %5u unrecognized rpcbind error (%d)\n",
1074 task->tk_pid, -task->tk_status); 1090 task->tk_pid, -task->tk_status);
@@ -1180,11 +1196,25 @@ static void
1180call_transmit_status(struct rpc_task *task) 1196call_transmit_status(struct rpc_task *task)
1181{ 1197{
1182 task->tk_action = call_status; 1198 task->tk_action = call_status;
1199
1200 /*
1201 * Common case: success. Force the compiler to put this
1202 * test first.
1203 */
1204 if (task->tk_status == 0) {
1205 xprt_end_transmit(task);
1206 rpc_task_force_reencode(task);
1207 return;
1208 }
1209
1183 switch (task->tk_status) { 1210 switch (task->tk_status) {
1184 case -EAGAIN: 1211 case -EAGAIN:
1185 break; 1212 break;
1186 default: 1213 default:
1214 dprint_status(task);
1187 xprt_end_transmit(task); 1215 xprt_end_transmit(task);
1216 rpc_task_force_reencode(task);
1217 break;
1188 /* 1218 /*
1189 * Special cases: if we've been waiting on the 1219 * Special cases: if we've been waiting on the
1190 * socket's write_space() callback, or if the 1220 * socket's write_space() callback, or if the
@@ -1192,11 +1222,16 @@ call_transmit_status(struct rpc_task *task)
1192 * then hold onto the transport lock. 1222 * then hold onto the transport lock.
1193 */ 1223 */
1194 case -ECONNREFUSED: 1224 case -ECONNREFUSED:
1195 case -ECONNRESET:
1196 case -ENOTCONN:
1197 case -EHOSTDOWN: 1225 case -EHOSTDOWN:
1198 case -EHOSTUNREACH: 1226 case -EHOSTUNREACH:
1199 case -ENETUNREACH: 1227 case -ENETUNREACH:
1228 if (RPC_IS_SOFTCONN(task)) {
1229 xprt_end_transmit(task);
1230 rpc_exit(task, task->tk_status);
1231 break;
1232 }
1233 case -ECONNRESET:
1234 case -ENOTCONN:
1200 case -EPIPE: 1235 case -EPIPE:
1201 rpc_task_force_reencode(task); 1236 rpc_task_force_reencode(task);
1202 } 1237 }
@@ -1346,6 +1381,10 @@ call_timeout(struct rpc_task *task)
1346 dprintk("RPC: %5u call_timeout (major)\n", task->tk_pid); 1381 dprintk("RPC: %5u call_timeout (major)\n", task->tk_pid);
1347 task->tk_timeouts++; 1382 task->tk_timeouts++;
1348 1383
1384 if (RPC_IS_SOFTCONN(task)) {
1385 rpc_exit(task, -ETIMEDOUT);
1386 return;
1387 }
1349 if (RPC_IS_SOFT(task)) { 1388 if (RPC_IS_SOFT(task)) {
1350 if (clnt->cl_chatty) 1389 if (clnt->cl_chatty)
1351 printk(KERN_NOTICE "%s: server %s not responding, timed out\n", 1390 printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
@@ -1675,14 +1714,14 @@ static struct rpc_procinfo rpcproc_null = {
1675 .p_decode = rpcproc_decode_null, 1714 .p_decode = rpcproc_decode_null,
1676}; 1715};
1677 1716
1678static int rpc_ping(struct rpc_clnt *clnt, int flags) 1717static int rpc_ping(struct rpc_clnt *clnt)
1679{ 1718{
1680 struct rpc_message msg = { 1719 struct rpc_message msg = {
1681 .rpc_proc = &rpcproc_null, 1720 .rpc_proc = &rpcproc_null,
1682 }; 1721 };
1683 int err; 1722 int err;
1684 msg.rpc_cred = authnull_ops.lookup_cred(NULL, NULL, 0); 1723 msg.rpc_cred = authnull_ops.lookup_cred(NULL, NULL, 0);
1685 err = rpc_call_sync(clnt, &msg, flags); 1724 err = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN);
1686 put_rpccred(msg.rpc_cred); 1725 put_rpccred(msg.rpc_cred);
1687 return err; 1726 return err;
1688} 1727}