diff options
Diffstat (limited to 'net/sunrpc/clnt.c')
| -rw-r--r-- | net/sunrpc/clnt.c | 161 |
1 files changed, 92 insertions, 69 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 8945307556ec..76739e928d0d 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
| 28 | #include <linux/kallsyms.h> | ||
| 28 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
| 29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 30 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
| @@ -58,7 +59,6 @@ static void call_start(struct rpc_task *task); | |||
| 58 | static void call_reserve(struct rpc_task *task); | 59 | static void call_reserve(struct rpc_task *task); |
| 59 | static void call_reserveresult(struct rpc_task *task); | 60 | static void call_reserveresult(struct rpc_task *task); |
| 60 | static void call_allocate(struct rpc_task *task); | 61 | static void call_allocate(struct rpc_task *task); |
| 61 | static void call_encode(struct rpc_task *task); | ||
| 62 | static void call_decode(struct rpc_task *task); | 62 | static void call_decode(struct rpc_task *task); |
| 63 | static void call_bind(struct rpc_task *task); | 63 | static void call_bind(struct rpc_task *task); |
| 64 | static void call_bind_status(struct rpc_task *task); | 64 | static void call_bind_status(struct rpc_task *task); |
| @@ -70,9 +70,9 @@ static void call_refreshresult(struct rpc_task *task); | |||
| 70 | static void call_timeout(struct rpc_task *task); | 70 | static void call_timeout(struct rpc_task *task); |
| 71 | static void call_connect(struct rpc_task *task); | 71 | static void call_connect(struct rpc_task *task); |
| 72 | static void call_connect_status(struct rpc_task *task); | 72 | static void call_connect_status(struct rpc_task *task); |
| 73 | static __be32 * call_header(struct rpc_task *task); | ||
| 74 | static __be32 * call_verify(struct rpc_task *task); | ||
| 75 | 73 | ||
| 74 | static __be32 *rpc_encode_header(struct rpc_task *task); | ||
| 75 | static __be32 *rpc_verify_header(struct rpc_task *task); | ||
| 76 | static int rpc_ping(struct rpc_clnt *clnt, int flags); | 76 | static int rpc_ping(struct rpc_clnt *clnt, int flags); |
| 77 | 77 | ||
| 78 | static void rpc_register_client(struct rpc_clnt *clnt) | 78 | static void rpc_register_client(struct rpc_clnt *clnt) |
| @@ -324,6 +324,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
| 324 | clnt->cl_autobind = 1; | 324 | clnt->cl_autobind = 1; |
| 325 | if (args->flags & RPC_CLNT_CREATE_DISCRTRY) | 325 | if (args->flags & RPC_CLNT_CREATE_DISCRTRY) |
| 326 | clnt->cl_discrtry = 1; | 326 | clnt->cl_discrtry = 1; |
| 327 | if (!(args->flags & RPC_CLNT_CREATE_QUIET)) | ||
| 328 | clnt->cl_chatty = 1; | ||
| 327 | 329 | ||
| 328 | return clnt; | 330 | return clnt; |
| 329 | } | 331 | } |
| @@ -690,6 +692,21 @@ rpc_restart_call(struct rpc_task *task) | |||
| 690 | } | 692 | } |
| 691 | EXPORT_SYMBOL_GPL(rpc_restart_call); | 693 | EXPORT_SYMBOL_GPL(rpc_restart_call); |
| 692 | 694 | ||
| 695 | #ifdef RPC_DEBUG | ||
| 696 | static const char *rpc_proc_name(const struct rpc_task *task) | ||
| 697 | { | ||
| 698 | const struct rpc_procinfo *proc = task->tk_msg.rpc_proc; | ||
| 699 | |||
| 700 | if (proc) { | ||
| 701 | if (proc->p_name) | ||
| 702 | return proc->p_name; | ||
| 703 | else | ||
| 704 | return "NULL"; | ||
| 705 | } else | ||
| 706 | return "no proc"; | ||
| 707 | } | ||
| 708 | #endif | ||
| 709 | |||
| 693 | /* | 710 | /* |
| 694 | * 0. Initial state | 711 | * 0. Initial state |
| 695 | * | 712 | * |
| @@ -701,9 +718,9 @@ call_start(struct rpc_task *task) | |||
| 701 | { | 718 | { |
| 702 | struct rpc_clnt *clnt = task->tk_client; | 719 | struct rpc_clnt *clnt = task->tk_client; |
| 703 | 720 | ||
| 704 | dprintk("RPC: %5u call_start %s%d proc %d (%s)\n", task->tk_pid, | 721 | dprintk("RPC: %5u call_start %s%d proc %s (%s)\n", task->tk_pid, |
| 705 | clnt->cl_protname, clnt->cl_vers, | 722 | clnt->cl_protname, clnt->cl_vers, |
| 706 | task->tk_msg.rpc_proc->p_proc, | 723 | rpc_proc_name(task), |
| 707 | (RPC_IS_ASYNC(task) ? "async" : "sync")); | 724 | (RPC_IS_ASYNC(task) ? "async" : "sync")); |
| 708 | 725 | ||
| 709 | /* Increment call count */ | 726 | /* Increment call count */ |
| @@ -861,7 +878,7 @@ rpc_xdr_buf_init(struct xdr_buf *buf, void *start, size_t len) | |||
| 861 | * 3. Encode arguments of an RPC call | 878 | * 3. Encode arguments of an RPC call |
| 862 | */ | 879 | */ |
| 863 | static void | 880 | static void |
| 864 | call_encode(struct rpc_task *task) | 881 | rpc_xdr_encode(struct rpc_task *task) |
| 865 | { | 882 | { |
| 866 | struct rpc_rqst *req = task->tk_rqstp; | 883 | struct rpc_rqst *req = task->tk_rqstp; |
| 867 | kxdrproc_t encode; | 884 | kxdrproc_t encode; |
| @@ -876,23 +893,19 @@ call_encode(struct rpc_task *task) | |||
| 876 | (char *)req->rq_buffer + req->rq_callsize, | 893 | (char *)req->rq_buffer + req->rq_callsize, |
| 877 | req->rq_rcvsize); | 894 | req->rq_rcvsize); |
| 878 | 895 | ||
| 879 | /* Encode header and provided arguments */ | 896 | p = rpc_encode_header(task); |
| 880 | encode = task->tk_msg.rpc_proc->p_encode; | 897 | if (p == NULL) { |
| 881 | if (!(p = call_header(task))) { | 898 | printk(KERN_INFO "RPC: couldn't encode RPC header, exit EIO\n"); |
| 882 | printk(KERN_INFO "RPC: call_header failed, exit EIO\n"); | ||
| 883 | rpc_exit(task, -EIO); | 899 | rpc_exit(task, -EIO); |
| 884 | return; | 900 | return; |
| 885 | } | 901 | } |
| 902 | |||
| 903 | encode = task->tk_msg.rpc_proc->p_encode; | ||
| 886 | if (encode == NULL) | 904 | if (encode == NULL) |
| 887 | return; | 905 | return; |
| 888 | 906 | ||
| 889 | task->tk_status = rpcauth_wrap_req(task, encode, req, p, | 907 | task->tk_status = rpcauth_wrap_req(task, encode, req, p, |
| 890 | task->tk_msg.rpc_argp); | 908 | task->tk_msg.rpc_argp); |
| 891 | if (task->tk_status == -ENOMEM) { | ||
| 892 | /* XXX: Is this sane? */ | ||
| 893 | rpc_delay(task, 3*HZ); | ||
| 894 | task->tk_status = -EAGAIN; | ||
| 895 | } | ||
| 896 | } | 909 | } |
| 897 | 910 | ||
| 898 | /* | 911 | /* |
| @@ -929,11 +942,9 @@ call_bind_status(struct rpc_task *task) | |||
| 929 | } | 942 | } |
| 930 | 943 | ||
| 931 | switch (task->tk_status) { | 944 | switch (task->tk_status) { |
| 932 | case -EAGAIN: | 945 | case -ENOMEM: |
| 933 | dprintk("RPC: %5u rpcbind waiting for another request " | 946 | dprintk("RPC: %5u rpcbind out of memory\n", task->tk_pid); |
| 934 | "to finish\n", task->tk_pid); | 947 | rpc_delay(task, HZ >> 2); |
| 935 | /* avoid busy-waiting here -- could be a network outage. */ | ||
| 936 | rpc_delay(task, 5*HZ); | ||
| 937 | goto retry_timeout; | 948 | goto retry_timeout; |
| 938 | case -EACCES: | 949 | case -EACCES: |
| 939 | dprintk("RPC: %5u remote rpcbind: RPC program/version " | 950 | dprintk("RPC: %5u remote rpcbind: RPC program/version " |
| @@ -1046,10 +1057,16 @@ call_transmit(struct rpc_task *task) | |||
| 1046 | /* Encode here so that rpcsec_gss can use correct sequence number. */ | 1057 | /* Encode here so that rpcsec_gss can use correct sequence number. */ |
| 1047 | if (rpc_task_need_encode(task)) { | 1058 | if (rpc_task_need_encode(task)) { |
| 1048 | BUG_ON(task->tk_rqstp->rq_bytes_sent != 0); | 1059 | BUG_ON(task->tk_rqstp->rq_bytes_sent != 0); |
| 1049 | call_encode(task); | 1060 | rpc_xdr_encode(task); |
| 1050 | /* Did the encode result in an error condition? */ | 1061 | /* Did the encode result in an error condition? */ |
| 1051 | if (task->tk_status != 0) | 1062 | if (task->tk_status != 0) { |
| 1063 | /* Was the error nonfatal? */ | ||
| 1064 | if (task->tk_status == -EAGAIN) | ||
| 1065 | rpc_delay(task, HZ >> 4); | ||
| 1066 | else | ||
| 1067 | rpc_exit(task, task->tk_status); | ||
| 1052 | return; | 1068 | return; |
| 1069 | } | ||
| 1053 | } | 1070 | } |
| 1054 | xprt_transmit(task); | 1071 | xprt_transmit(task); |
| 1055 | if (task->tk_status < 0) | 1072 | if (task->tk_status < 0) |
| @@ -1132,7 +1149,8 @@ call_status(struct rpc_task *task) | |||
| 1132 | rpc_exit(task, status); | 1149 | rpc_exit(task, status); |
| 1133 | break; | 1150 | break; |
| 1134 | default: | 1151 | default: |
| 1135 | printk("%s: RPC call returned error %d\n", | 1152 | if (clnt->cl_chatty) |
| 1153 | printk("%s: RPC call returned error %d\n", | ||
| 1136 | clnt->cl_protname, -status); | 1154 | clnt->cl_protname, -status); |
| 1137 | rpc_exit(task, status); | 1155 | rpc_exit(task, status); |
| 1138 | } | 1156 | } |
| @@ -1157,7 +1175,8 @@ call_timeout(struct rpc_task *task) | |||
| 1157 | task->tk_timeouts++; | 1175 | task->tk_timeouts++; |
| 1158 | 1176 | ||
| 1159 | if (RPC_IS_SOFT(task)) { | 1177 | if (RPC_IS_SOFT(task)) { |
| 1160 | printk(KERN_NOTICE "%s: server %s not responding, timed out\n", | 1178 | if (clnt->cl_chatty) |
| 1179 | printk(KERN_NOTICE "%s: server %s not responding, timed out\n", | ||
| 1161 | clnt->cl_protname, clnt->cl_server); | 1180 | clnt->cl_protname, clnt->cl_server); |
| 1162 | rpc_exit(task, -EIO); | 1181 | rpc_exit(task, -EIO); |
| 1163 | return; | 1182 | return; |
| @@ -1165,7 +1184,8 @@ call_timeout(struct rpc_task *task) | |||
| 1165 | 1184 | ||
| 1166 | if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) { | 1185 | if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) { |
| 1167 | task->tk_flags |= RPC_CALL_MAJORSEEN; | 1186 | task->tk_flags |= RPC_CALL_MAJORSEEN; |
| 1168 | printk(KERN_NOTICE "%s: server %s not responding, still trying\n", | 1187 | if (clnt->cl_chatty) |
| 1188 | printk(KERN_NOTICE "%s: server %s not responding, still trying\n", | ||
| 1169 | clnt->cl_protname, clnt->cl_server); | 1189 | clnt->cl_protname, clnt->cl_server); |
| 1170 | } | 1190 | } |
| 1171 | rpc_force_rebind(clnt); | 1191 | rpc_force_rebind(clnt); |
| @@ -1196,8 +1216,9 @@ call_decode(struct rpc_task *task) | |||
| 1196 | task->tk_pid, task->tk_status); | 1216 | task->tk_pid, task->tk_status); |
| 1197 | 1217 | ||
| 1198 | if (task->tk_flags & RPC_CALL_MAJORSEEN) { | 1218 | if (task->tk_flags & RPC_CALL_MAJORSEEN) { |
| 1199 | printk(KERN_NOTICE "%s: server %s OK\n", | 1219 | if (clnt->cl_chatty) |
| 1200 | clnt->cl_protname, clnt->cl_server); | 1220 | printk(KERN_NOTICE "%s: server %s OK\n", |
| 1221 | clnt->cl_protname, clnt->cl_server); | ||
| 1201 | task->tk_flags &= ~RPC_CALL_MAJORSEEN; | 1222 | task->tk_flags &= ~RPC_CALL_MAJORSEEN; |
| 1202 | } | 1223 | } |
| 1203 | 1224 | ||
| @@ -1224,8 +1245,7 @@ call_decode(struct rpc_task *task) | |||
| 1224 | goto out_retry; | 1245 | goto out_retry; |
| 1225 | } | 1246 | } |
| 1226 | 1247 | ||
| 1227 | /* Verify the RPC header */ | 1248 | p = rpc_verify_header(task); |
| 1228 | p = call_verify(task); | ||
| 1229 | if (IS_ERR(p)) { | 1249 | if (IS_ERR(p)) { |
| 1230 | if (p == ERR_PTR(-EAGAIN)) | 1250 | if (p == ERR_PTR(-EAGAIN)) |
| 1231 | goto out_retry; | 1251 | goto out_retry; |
| @@ -1243,7 +1263,7 @@ call_decode(struct rpc_task *task) | |||
| 1243 | return; | 1263 | return; |
| 1244 | out_retry: | 1264 | out_retry: |
| 1245 | task->tk_status = 0; | 1265 | task->tk_status = 0; |
| 1246 | /* Note: call_verify() may have freed the RPC slot */ | 1266 | /* Note: rpc_verify_header() may have freed the RPC slot */ |
| 1247 | if (task->tk_rqstp == req) { | 1267 | if (task->tk_rqstp == req) { |
| 1248 | req->rq_received = req->rq_rcv_buf.len = 0; | 1268 | req->rq_received = req->rq_rcv_buf.len = 0; |
| 1249 | if (task->tk_client->cl_discrtry) | 1269 | if (task->tk_client->cl_discrtry) |
| @@ -1290,11 +1310,8 @@ call_refreshresult(struct rpc_task *task) | |||
| 1290 | return; | 1310 | return; |
| 1291 | } | 1311 | } |
| 1292 | 1312 | ||
| 1293 | /* | ||
| 1294 | * Call header serialization | ||
| 1295 | */ | ||
| 1296 | static __be32 * | 1313 | static __be32 * |
| 1297 | call_header(struct rpc_task *task) | 1314 | rpc_encode_header(struct rpc_task *task) |
| 1298 | { | 1315 | { |
| 1299 | struct rpc_clnt *clnt = task->tk_client; | 1316 | struct rpc_clnt *clnt = task->tk_client; |
| 1300 | struct rpc_rqst *req = task->tk_rqstp; | 1317 | struct rpc_rqst *req = task->tk_rqstp; |
| @@ -1314,11 +1331,8 @@ call_header(struct rpc_task *task) | |||
| 1314 | return p; | 1331 | return p; |
| 1315 | } | 1332 | } |
| 1316 | 1333 | ||
| 1317 | /* | ||
| 1318 | * Reply header verification | ||
| 1319 | */ | ||
| 1320 | static __be32 * | 1334 | static __be32 * |
| 1321 | call_verify(struct rpc_task *task) | 1335 | rpc_verify_header(struct rpc_task *task) |
| 1322 | { | 1336 | { |
| 1323 | struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0]; | 1337 | struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0]; |
| 1324 | int len = task->tk_rqstp->rq_rcv_buf.len >> 2; | 1338 | int len = task->tk_rqstp->rq_rcv_buf.len >> 2; |
| @@ -1392,7 +1406,7 @@ call_verify(struct rpc_task *task) | |||
| 1392 | task->tk_action = call_bind; | 1406 | task->tk_action = call_bind; |
| 1393 | goto out_retry; | 1407 | goto out_retry; |
| 1394 | case RPC_AUTH_TOOWEAK: | 1408 | case RPC_AUTH_TOOWEAK: |
| 1395 | printk(KERN_NOTICE "call_verify: server %s requires stronger " | 1409 | printk(KERN_NOTICE "RPC: server %s requires stronger " |
| 1396 | "authentication.\n", task->tk_client->cl_server); | 1410 | "authentication.\n", task->tk_client->cl_server); |
| 1397 | break; | 1411 | break; |
| 1398 | default: | 1412 | default: |
| @@ -1431,10 +1445,10 @@ call_verify(struct rpc_task *task) | |||
| 1431 | error = -EPROTONOSUPPORT; | 1445 | error = -EPROTONOSUPPORT; |
| 1432 | goto out_err; | 1446 | goto out_err; |
| 1433 | case RPC_PROC_UNAVAIL: | 1447 | case RPC_PROC_UNAVAIL: |
| 1434 | dprintk("RPC: %5u %s: proc %p unsupported by program %u, " | 1448 | dprintk("RPC: %5u %s: proc %s unsupported by program %u, " |
| 1435 | "version %u on server %s\n", | 1449 | "version %u on server %s\n", |
| 1436 | task->tk_pid, __func__, | 1450 | task->tk_pid, __func__, |
| 1437 | task->tk_msg.rpc_proc, | 1451 | rpc_proc_name(task), |
| 1438 | task->tk_client->cl_prog, | 1452 | task->tk_client->cl_prog, |
| 1439 | task->tk_client->cl_vers, | 1453 | task->tk_client->cl_vers, |
| 1440 | task->tk_client->cl_server); | 1454 | task->tk_client->cl_server); |
| @@ -1517,44 +1531,53 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int | |||
| 1517 | EXPORT_SYMBOL_GPL(rpc_call_null); | 1531 | EXPORT_SYMBOL_GPL(rpc_call_null); |
| 1518 | 1532 | ||
| 1519 | #ifdef RPC_DEBUG | 1533 | #ifdef RPC_DEBUG |
| 1534 | static void rpc_show_header(void) | ||
| 1535 | { | ||
| 1536 | printk(KERN_INFO "-pid- flgs status -client- --rqstp- " | ||
| 1537 | "-timeout ---ops--\n"); | ||
| 1538 | } | ||
| 1539 | |||
| 1540 | static void rpc_show_task(const struct rpc_clnt *clnt, | ||
| 1541 | const struct rpc_task *task) | ||
| 1542 | { | ||
| 1543 | const char *rpc_waitq = "none"; | ||
| 1544 | char *p, action[KSYM_SYMBOL_LEN]; | ||
| 1545 | |||
| 1546 | if (RPC_IS_QUEUED(task)) | ||
| 1547 | rpc_waitq = rpc_qname(task->tk_waitqueue); | ||
| 1548 | |||
| 1549 | /* map tk_action pointer to a function name; then trim off | ||
| 1550 | * the "+0x0 [sunrpc]" */ | ||
| 1551 | sprint_symbol(action, (unsigned long)task->tk_action); | ||
| 1552 | p = strchr(action, '+'); | ||
| 1553 | if (p) | ||
| 1554 | *p = '\0'; | ||
| 1555 | |||
| 1556 | printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%s q:%s\n", | ||
| 1557 | task->tk_pid, task->tk_flags, task->tk_status, | ||
| 1558 | clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops, | ||
| 1559 | clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task), | ||
| 1560 | action, rpc_waitq); | ||
| 1561 | } | ||
| 1562 | |||
| 1520 | void rpc_show_tasks(void) | 1563 | void rpc_show_tasks(void) |
| 1521 | { | 1564 | { |
| 1522 | struct rpc_clnt *clnt; | 1565 | struct rpc_clnt *clnt; |
| 1523 | struct rpc_task *t; | 1566 | struct rpc_task *task; |
| 1567 | int header = 0; | ||
| 1524 | 1568 | ||
| 1525 | spin_lock(&rpc_client_lock); | 1569 | spin_lock(&rpc_client_lock); |
| 1526 | if (list_empty(&all_clients)) | ||
| 1527 | goto out; | ||
| 1528 | printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout " | ||
| 1529 | "-rpcwait -action- ---ops--\n"); | ||
| 1530 | list_for_each_entry(clnt, &all_clients, cl_clients) { | 1570 | list_for_each_entry(clnt, &all_clients, cl_clients) { |
| 1531 | if (list_empty(&clnt->cl_tasks)) | ||
| 1532 | continue; | ||
| 1533 | spin_lock(&clnt->cl_lock); | 1571 | spin_lock(&clnt->cl_lock); |
| 1534 | list_for_each_entry(t, &clnt->cl_tasks, tk_task) { | 1572 | list_for_each_entry(task, &clnt->cl_tasks, tk_task) { |
| 1535 | const char *rpc_waitq = "none"; | 1573 | if (!header) { |
| 1536 | int proc; | 1574 | rpc_show_header(); |
| 1537 | 1575 | header++; | |
| 1538 | if (t->tk_msg.rpc_proc) | 1576 | } |
| 1539 | proc = t->tk_msg.rpc_proc->p_proc; | 1577 | rpc_show_task(clnt, task); |
| 1540 | else | ||
| 1541 | proc = -1; | ||
| 1542 | |||
| 1543 | if (RPC_IS_QUEUED(t)) | ||
| 1544 | rpc_waitq = rpc_qname(t->tk_waitqueue); | ||
| 1545 | |||
| 1546 | printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n", | ||
| 1547 | t->tk_pid, proc, | ||
| 1548 | t->tk_flags, t->tk_status, | ||
| 1549 | t->tk_client, | ||
| 1550 | (t->tk_client ? t->tk_client->cl_prog : 0), | ||
| 1551 | t->tk_rqstp, t->tk_timeout, | ||
| 1552 | rpc_waitq, | ||
| 1553 | t->tk_action, t->tk_ops); | ||
| 1554 | } | 1578 | } |
| 1555 | spin_unlock(&clnt->cl_lock); | 1579 | spin_unlock(&clnt->cl_lock); |
| 1556 | } | 1580 | } |
| 1557 | out: | ||
| 1558 | spin_unlock(&rpc_client_lock); | 1581 | spin_unlock(&rpc_client_lock); |
| 1559 | } | 1582 | } |
| 1560 | #endif | 1583 | #endif |
