diff options
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r-- | net/sunrpc/clnt.c | 105 |
1 files changed, 58 insertions, 47 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index fa5549079d79..8c9141583d6f 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -13,10 +13,6 @@ | |||
13 | * and need to be refreshed, or when a packet was damaged in transit. | 13 | * and need to be refreshed, or when a packet was damaged in transit. |
14 | * This may be have to be moved to the VFS layer. | 14 | * This may be have to be moved to the VFS layer. |
15 | * | 15 | * |
16 | * NB: BSD uses a more intelligent approach to guessing when a request | ||
17 | * or reply has been lost by keeping the RTO estimate for each procedure. | ||
18 | * We currently make do with a constant timeout value. | ||
19 | * | ||
20 | * Copyright (C) 1992,1993 Rick Sladkey <jrs@world.std.com> | 16 | * Copyright (C) 1992,1993 Rick Sladkey <jrs@world.std.com> |
21 | * Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de> | 17 | * Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de> |
22 | */ | 18 | */ |
@@ -32,7 +28,9 @@ | |||
32 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
33 | #include <linux/utsname.h> | 29 | #include <linux/utsname.h> |
34 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
31 | #include <linux/in.h> | ||
35 | #include <linux/in6.h> | 32 | #include <linux/in6.h> |
33 | #include <linux/un.h> | ||
36 | 34 | ||
37 | #include <linux/sunrpc/clnt.h> | 35 | #include <linux/sunrpc/clnt.h> |
38 | #include <linux/sunrpc/rpc_pipe_fs.h> | 36 | #include <linux/sunrpc/rpc_pipe_fs.h> |
@@ -284,6 +282,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
284 | struct rpc_xprt *xprt; | 282 | struct rpc_xprt *xprt; |
285 | struct rpc_clnt *clnt; | 283 | struct rpc_clnt *clnt; |
286 | struct xprt_create xprtargs = { | 284 | struct xprt_create xprtargs = { |
285 | .net = args->net, | ||
287 | .ident = args->protocol, | 286 | .ident = args->protocol, |
288 | .srcaddr = args->saddress, | 287 | .srcaddr = args->saddress, |
289 | .dstaddr = args->address, | 288 | .dstaddr = args->address, |
@@ -297,22 +296,27 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
297 | * up a string representation of the passed-in address. | 296 | * up a string representation of the passed-in address. |
298 | */ | 297 | */ |
299 | if (args->servername == NULL) { | 298 | if (args->servername == NULL) { |
299 | struct sockaddr_un *sun = | ||
300 | (struct sockaddr_un *)args->address; | ||
301 | struct sockaddr_in *sin = | ||
302 | (struct sockaddr_in *)args->address; | ||
303 | struct sockaddr_in6 *sin6 = | ||
304 | (struct sockaddr_in6 *)args->address; | ||
305 | |||
300 | servername[0] = '\0'; | 306 | servername[0] = '\0'; |
301 | switch (args->address->sa_family) { | 307 | switch (args->address->sa_family) { |
302 | case AF_INET: { | 308 | case AF_LOCAL: |
303 | struct sockaddr_in *sin = | 309 | snprintf(servername, sizeof(servername), "%s", |
304 | (struct sockaddr_in *)args->address; | 310 | sun->sun_path); |
311 | break; | ||
312 | case AF_INET: | ||
305 | snprintf(servername, sizeof(servername), "%pI4", | 313 | snprintf(servername, sizeof(servername), "%pI4", |
306 | &sin->sin_addr.s_addr); | 314 | &sin->sin_addr.s_addr); |
307 | break; | 315 | break; |
308 | } | 316 | case AF_INET6: |
309 | case AF_INET6: { | ||
310 | struct sockaddr_in6 *sin = | ||
311 | (struct sockaddr_in6 *)args->address; | ||
312 | snprintf(servername, sizeof(servername), "%pI6", | 317 | snprintf(servername, sizeof(servername), "%pI6", |
313 | &sin->sin6_addr); | 318 | &sin6->sin6_addr); |
314 | break; | 319 | break; |
315 | } | ||
316 | default: | 320 | default: |
317 | /* caller wants default server name, but | 321 | /* caller wants default server name, but |
318 | * address family isn't recognized. */ | 322 | * address family isn't recognized. */ |
@@ -435,7 +439,9 @@ void rpc_killall_tasks(struct rpc_clnt *clnt) | |||
435 | if (!(rovr->tk_flags & RPC_TASK_KILLED)) { | 439 | if (!(rovr->tk_flags & RPC_TASK_KILLED)) { |
436 | rovr->tk_flags |= RPC_TASK_KILLED; | 440 | rovr->tk_flags |= RPC_TASK_KILLED; |
437 | rpc_exit(rovr, -EIO); | 441 | rpc_exit(rovr, -EIO); |
438 | rpc_wake_up_queued_task(rovr->tk_waitqueue, rovr); | 442 | if (RPC_IS_QUEUED(rovr)) |
443 | rpc_wake_up_queued_task(rovr->tk_waitqueue, | ||
444 | rovr); | ||
439 | } | 445 | } |
440 | } | 446 | } |
441 | spin_unlock(&clnt->cl_lock); | 447 | spin_unlock(&clnt->cl_lock); |
@@ -596,6 +602,14 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt) | |||
596 | } | 602 | } |
597 | } | 603 | } |
598 | 604 | ||
605 | void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt) | ||
606 | { | ||
607 | rpc_task_release_client(task); | ||
608 | rpc_task_set_client(task, clnt); | ||
609 | } | ||
610 | EXPORT_SYMBOL_GPL(rpc_task_reset_client); | ||
611 | |||
612 | |||
599 | static void | 613 | static void |
600 | rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg) | 614 | rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg) |
601 | { | 615 | { |
@@ -635,12 +649,6 @@ struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data) | |||
635 | rpc_task_set_client(task, task_setup_data->rpc_client); | 649 | rpc_task_set_client(task, task_setup_data->rpc_client); |
636 | rpc_task_set_rpc_message(task, task_setup_data->rpc_message); | 650 | rpc_task_set_rpc_message(task, task_setup_data->rpc_message); |
637 | 651 | ||
638 | if (task->tk_status != 0) { | ||
639 | int ret = task->tk_status; | ||
640 | rpc_put_task(task); | ||
641 | return ERR_PTR(ret); | ||
642 | } | ||
643 | |||
644 | if (task->tk_action == NULL) | 652 | if (task->tk_action == NULL) |
645 | rpc_call_start(task); | 653 | rpc_call_start(task); |
646 | 654 | ||
@@ -988,20 +996,26 @@ call_refreshresult(struct rpc_task *task) | |||
988 | dprint_status(task); | 996 | dprint_status(task); |
989 | 997 | ||
990 | task->tk_status = 0; | 998 | task->tk_status = 0; |
991 | task->tk_action = call_allocate; | 999 | task->tk_action = call_refresh; |
992 | if (status >= 0 && rpcauth_uptodatecred(task)) | ||
993 | return; | ||
994 | switch (status) { | 1000 | switch (status) { |
995 | case -EACCES: | 1001 | case 0: |
996 | rpc_exit(task, -EACCES); | 1002 | if (rpcauth_uptodatecred(task)) |
997 | return; | 1003 | task->tk_action = call_allocate; |
998 | case -ENOMEM: | ||
999 | rpc_exit(task, -ENOMEM); | ||
1000 | return; | 1004 | return; |
1001 | case -ETIMEDOUT: | 1005 | case -ETIMEDOUT: |
1002 | rpc_delay(task, 3*HZ); | 1006 | rpc_delay(task, 3*HZ); |
1007 | case -EAGAIN: | ||
1008 | status = -EACCES; | ||
1009 | if (!task->tk_cred_retry) | ||
1010 | break; | ||
1011 | task->tk_cred_retry--; | ||
1012 | dprintk("RPC: %5u %s: retry refresh creds\n", | ||
1013 | task->tk_pid, __func__); | ||
1014 | return; | ||
1003 | } | 1015 | } |
1004 | task->tk_action = call_refresh; | 1016 | dprintk("RPC: %5u %s: refresh creds failed with error %d\n", |
1017 | task->tk_pid, __func__, status); | ||
1018 | rpc_exit(task, status); | ||
1005 | } | 1019 | } |
1006 | 1020 | ||
1007 | /* | 1021 | /* |
@@ -1047,7 +1061,7 @@ call_allocate(struct rpc_task *task) | |||
1047 | 1061 | ||
1048 | dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid); | 1062 | dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid); |
1049 | 1063 | ||
1050 | if (RPC_IS_ASYNC(task) || !signalled()) { | 1064 | if (RPC_IS_ASYNC(task) || !fatal_signal_pending(current)) { |
1051 | task->tk_action = call_allocate; | 1065 | task->tk_action = call_allocate; |
1052 | rpc_delay(task, HZ>>4); | 1066 | rpc_delay(task, HZ>>4); |
1053 | return; | 1067 | return; |
@@ -1088,7 +1102,7 @@ static void | |||
1088 | rpc_xdr_encode(struct rpc_task *task) | 1102 | rpc_xdr_encode(struct rpc_task *task) |
1089 | { | 1103 | { |
1090 | struct rpc_rqst *req = task->tk_rqstp; | 1104 | struct rpc_rqst *req = task->tk_rqstp; |
1091 | kxdrproc_t encode; | 1105 | kxdreproc_t encode; |
1092 | __be32 *p; | 1106 | __be32 *p; |
1093 | 1107 | ||
1094 | dprint_status(task); | 1108 | dprint_status(task); |
@@ -1161,6 +1175,9 @@ call_bind_status(struct rpc_task *task) | |||
1161 | status = -EOPNOTSUPP; | 1175 | status = -EOPNOTSUPP; |
1162 | break; | 1176 | break; |
1163 | } | 1177 | } |
1178 | if (task->tk_rebind_retry == 0) | ||
1179 | break; | ||
1180 | task->tk_rebind_retry--; | ||
1164 | rpc_delay(task, 3*HZ); | 1181 | rpc_delay(task, 3*HZ); |
1165 | goto retry_timeout; | 1182 | goto retry_timeout; |
1166 | case -ETIMEDOUT: | 1183 | case -ETIMEDOUT: |
@@ -1497,7 +1514,10 @@ call_timeout(struct rpc_task *task) | |||
1497 | if (clnt->cl_chatty) | 1514 | if (clnt->cl_chatty) |
1498 | printk(KERN_NOTICE "%s: server %s not responding, timed out\n", | 1515 | printk(KERN_NOTICE "%s: server %s not responding, timed out\n", |
1499 | clnt->cl_protname, clnt->cl_server); | 1516 | clnt->cl_protname, clnt->cl_server); |
1500 | rpc_exit(task, -EIO); | 1517 | if (task->tk_flags & RPC_TASK_TIMEOUT) |
1518 | rpc_exit(task, -ETIMEDOUT); | ||
1519 | else | ||
1520 | rpc_exit(task, -EIO); | ||
1501 | return; | 1521 | return; |
1502 | } | 1522 | } |
1503 | 1523 | ||
@@ -1528,7 +1548,7 @@ call_decode(struct rpc_task *task) | |||
1528 | { | 1548 | { |
1529 | struct rpc_clnt *clnt = task->tk_client; | 1549 | struct rpc_clnt *clnt = task->tk_client; |
1530 | struct rpc_rqst *req = task->tk_rqstp; | 1550 | struct rpc_rqst *req = task->tk_rqstp; |
1531 | kxdrproc_t decode = task->tk_msg.rpc_proc->p_decode; | 1551 | kxdrdproc_t decode = task->tk_msg.rpc_proc->p_decode; |
1532 | __be32 *p; | 1552 | __be32 *p; |
1533 | 1553 | ||
1534 | dprintk("RPC: %5u call_decode (status %d)\n", | 1554 | dprintk("RPC: %5u call_decode (status %d)\n", |
@@ -1675,7 +1695,7 @@ rpc_verify_header(struct rpc_task *task) | |||
1675 | rpcauth_invalcred(task); | 1695 | rpcauth_invalcred(task); |
1676 | /* Ensure we obtain a new XID! */ | 1696 | /* Ensure we obtain a new XID! */ |
1677 | xprt_release(task); | 1697 | xprt_release(task); |
1678 | task->tk_action = call_refresh; | 1698 | task->tk_action = call_reserve; |
1679 | goto out_retry; | 1699 | goto out_retry; |
1680 | case RPC_AUTH_BADCRED: | 1700 | case RPC_AUTH_BADCRED: |
1681 | case RPC_AUTH_BADVERF: | 1701 | case RPC_AUTH_BADVERF: |
@@ -1769,12 +1789,11 @@ out_overflow: | |||
1769 | goto out_garbage; | 1789 | goto out_garbage; |
1770 | } | 1790 | } |
1771 | 1791 | ||
1772 | static int rpcproc_encode_null(void *rqstp, __be32 *data, void *obj) | 1792 | static void rpcproc_encode_null(void *rqstp, struct xdr_stream *xdr, void *obj) |
1773 | { | 1793 | { |
1774 | return 0; | ||
1775 | } | 1794 | } |
1776 | 1795 | ||
1777 | static int rpcproc_decode_null(void *rqstp, __be32 *data, void *obj) | 1796 | static int rpcproc_decode_null(void *rqstp, struct xdr_stream *xdr, void *obj) |
1778 | { | 1797 | { |
1779 | return 0; | 1798 | return 0; |
1780 | } | 1799 | } |
@@ -1823,23 +1842,15 @@ static void rpc_show_task(const struct rpc_clnt *clnt, | |||
1823 | const struct rpc_task *task) | 1842 | const struct rpc_task *task) |
1824 | { | 1843 | { |
1825 | const char *rpc_waitq = "none"; | 1844 | const char *rpc_waitq = "none"; |
1826 | char *p, action[KSYM_SYMBOL_LEN]; | ||
1827 | 1845 | ||
1828 | if (RPC_IS_QUEUED(task)) | 1846 | if (RPC_IS_QUEUED(task)) |
1829 | rpc_waitq = rpc_qname(task->tk_waitqueue); | 1847 | rpc_waitq = rpc_qname(task->tk_waitqueue); |
1830 | 1848 | ||
1831 | /* map tk_action pointer to a function name; then trim off | 1849 | printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%ps q:%s\n", |
1832 | * the "+0x0 [sunrpc]" */ | ||
1833 | sprint_symbol(action, (unsigned long)task->tk_action); | ||
1834 | p = strchr(action, '+'); | ||
1835 | if (p) | ||
1836 | *p = '\0'; | ||
1837 | |||
1838 | printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%s q:%s\n", | ||
1839 | task->tk_pid, task->tk_flags, task->tk_status, | 1850 | task->tk_pid, task->tk_flags, task->tk_status, |
1840 | clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops, | 1851 | clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops, |
1841 | clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task), | 1852 | clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task), |
1842 | action, rpc_waitq); | 1853 | task->tk_action, rpc_waitq); |
1843 | } | 1854 | } |
1844 | 1855 | ||
1845 | void rpc_show_tasks(void) | 1856 | void rpc_show_tasks(void) |