diff options
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r-- | net/sunrpc/clnt.c | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 52429b1ffcc1..76be83ee4b04 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -127,7 +127,14 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s | |||
127 | struct rpc_clnt *clnt = NULL; | 127 | struct rpc_clnt *clnt = NULL; |
128 | struct rpc_auth *auth; | 128 | struct rpc_auth *auth; |
129 | int err; | 129 | int err; |
130 | int len; | 130 | size_t len; |
131 | |||
132 | /* sanity check the name before trying to print it */ | ||
133 | err = -EINVAL; | ||
134 | len = strlen(servname); | ||
135 | if (len > RPC_MAXNETNAMELEN) | ||
136 | goto out_no_rpciod; | ||
137 | len++; | ||
131 | 138 | ||
132 | dprintk("RPC: creating %s client for %s (xprt %p)\n", | 139 | dprintk("RPC: creating %s client for %s (xprt %p)\n", |
133 | program->name, servname, xprt); | 140 | program->name, servname, xprt); |
@@ -148,7 +155,6 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s | |||
148 | clnt->cl_parent = clnt; | 155 | clnt->cl_parent = clnt; |
149 | 156 | ||
150 | clnt->cl_server = clnt->cl_inline_name; | 157 | clnt->cl_server = clnt->cl_inline_name; |
151 | len = strlen(servname) + 1; | ||
152 | if (len > sizeof(clnt->cl_inline_name)) { | 158 | if (len > sizeof(clnt->cl_inline_name)) { |
153 | char *buf = kmalloc(len, GFP_KERNEL); | 159 | char *buf = kmalloc(len, GFP_KERNEL); |
154 | if (buf != 0) | 160 | if (buf != 0) |
@@ -234,8 +240,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
234 | { | 240 | { |
235 | struct rpc_xprt *xprt; | 241 | struct rpc_xprt *xprt; |
236 | struct rpc_clnt *clnt; | 242 | struct rpc_clnt *clnt; |
237 | struct rpc_xprtsock_create xprtargs = { | 243 | struct xprt_create xprtargs = { |
238 | .proto = args->protocol, | 244 | .ident = args->protocol, |
239 | .srcaddr = args->saddress, | 245 | .srcaddr = args->saddress, |
240 | .dstaddr = args->address, | 246 | .dstaddr = args->address, |
241 | .addrlen = args->addrsize, | 247 | .addrlen = args->addrsize, |
@@ -253,7 +259,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
253 | */ | 259 | */ |
254 | if (args->servername == NULL) { | 260 | if (args->servername == NULL) { |
255 | struct sockaddr_in *addr = | 261 | struct sockaddr_in *addr = |
256 | (struct sockaddr_in *) &args->address; | 262 | (struct sockaddr_in *) args->address; |
257 | snprintf(servername, sizeof(servername), NIPQUAD_FMT, | 263 | snprintf(servername, sizeof(servername), NIPQUAD_FMT, |
258 | NIPQUAD(addr->sin_addr.s_addr)); | 264 | NIPQUAD(addr->sin_addr.s_addr)); |
259 | args->servername = servername; | 265 | args->servername = servername; |
@@ -269,9 +275,6 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
269 | if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT) | 275 | if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT) |
270 | xprt->resvport = 0; | 276 | xprt->resvport = 0; |
271 | 277 | ||
272 | dprintk("RPC: creating %s client for %s (xprt %p)\n", | ||
273 | args->program->name, args->servername, xprt); | ||
274 | |||
275 | clnt = rpc_new_client(xprt, args->servername, args->program, | 278 | clnt = rpc_new_client(xprt, args->servername, args->program, |
276 | args->version, args->authflavor); | 279 | args->version, args->authflavor); |
277 | if (IS_ERR(clnt)) | 280 | if (IS_ERR(clnt)) |
@@ -439,7 +442,7 @@ rpc_release_client(struct rpc_clnt *clnt) | |||
439 | */ | 442 | */ |
440 | struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old, | 443 | struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old, |
441 | struct rpc_program *program, | 444 | struct rpc_program *program, |
442 | int vers) | 445 | u32 vers) |
443 | { | 446 | { |
444 | struct rpc_clnt *clnt; | 447 | struct rpc_clnt *clnt; |
445 | struct rpc_version *version; | 448 | struct rpc_version *version; |
@@ -843,8 +846,7 @@ call_allocate(struct rpc_task *task) | |||
843 | dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid); | 846 | dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid); |
844 | 847 | ||
845 | if (RPC_IS_ASYNC(task) || !signalled()) { | 848 | if (RPC_IS_ASYNC(task) || !signalled()) { |
846 | xprt_release(task); | 849 | task->tk_action = call_allocate; |
847 | task->tk_action = call_reserve; | ||
848 | rpc_delay(task, HZ>>4); | 850 | rpc_delay(task, HZ>>4); |
849 | return; | 851 | return; |
850 | } | 852 | } |
@@ -871,6 +873,7 @@ rpc_xdr_buf_init(struct xdr_buf *buf, void *start, size_t len) | |||
871 | buf->head[0].iov_len = len; | 873 | buf->head[0].iov_len = len; |
872 | buf->tail[0].iov_len = 0; | 874 | buf->tail[0].iov_len = 0; |
873 | buf->page_len = 0; | 875 | buf->page_len = 0; |
876 | buf->flags = 0; | ||
874 | buf->len = 0; | 877 | buf->len = 0; |
875 | buf->buflen = len; | 878 | buf->buflen = len; |
876 | } | 879 | } |
@@ -937,7 +940,7 @@ call_bind(struct rpc_task *task) | |||
937 | static void | 940 | static void |
938 | call_bind_status(struct rpc_task *task) | 941 | call_bind_status(struct rpc_task *task) |
939 | { | 942 | { |
940 | int status = -EACCES; | 943 | int status = -EIO; |
941 | 944 | ||
942 | if (task->tk_status >= 0) { | 945 | if (task->tk_status >= 0) { |
943 | dprint_status(task); | 946 | dprint_status(task); |
@@ -947,9 +950,20 @@ call_bind_status(struct rpc_task *task) | |||
947 | } | 950 | } |
948 | 951 | ||
949 | switch (task->tk_status) { | 952 | switch (task->tk_status) { |
953 | case -EAGAIN: | ||
954 | dprintk("RPC: %5u rpcbind waiting for another request " | ||
955 | "to finish\n", task->tk_pid); | ||
956 | /* avoid busy-waiting here -- could be a network outage. */ | ||
957 | rpc_delay(task, 5*HZ); | ||
958 | goto retry_timeout; | ||
950 | case -EACCES: | 959 | case -EACCES: |
951 | dprintk("RPC: %5u remote rpcbind: RPC program/version " | 960 | dprintk("RPC: %5u remote rpcbind: RPC program/version " |
952 | "unavailable\n", task->tk_pid); | 961 | "unavailable\n", task->tk_pid); |
962 | /* fail immediately if this is an RPC ping */ | ||
963 | if (task->tk_msg.rpc_proc->p_proc == 0) { | ||
964 | status = -EOPNOTSUPP; | ||
965 | break; | ||
966 | } | ||
953 | rpc_delay(task, 3*HZ); | 967 | rpc_delay(task, 3*HZ); |
954 | goto retry_timeout; | 968 | goto retry_timeout; |
955 | case -ETIMEDOUT: | 969 | case -ETIMEDOUT: |
@@ -957,6 +971,7 @@ call_bind_status(struct rpc_task *task) | |||
957 | task->tk_pid); | 971 | task->tk_pid); |
958 | goto retry_timeout; | 972 | goto retry_timeout; |
959 | case -EPFNOSUPPORT: | 973 | case -EPFNOSUPPORT: |
974 | /* server doesn't support any rpcbind version we know of */ | ||
960 | dprintk("RPC: %5u remote rpcbind service unavailable\n", | 975 | dprintk("RPC: %5u remote rpcbind service unavailable\n", |
961 | task->tk_pid); | 976 | task->tk_pid); |
962 | break; | 977 | break; |
@@ -969,7 +984,6 @@ call_bind_status(struct rpc_task *task) | |||
969 | default: | 984 | default: |
970 | dprintk("RPC: %5u unrecognized rpcbind error (%d)\n", | 985 | dprintk("RPC: %5u unrecognized rpcbind error (%d)\n", |
971 | task->tk_pid, -task->tk_status); | 986 | task->tk_pid, -task->tk_status); |
972 | status = -EIO; | ||
973 | } | 987 | } |
974 | 988 | ||
975 | rpc_exit(task, status); | 989 | rpc_exit(task, status); |
@@ -1257,7 +1271,6 @@ call_refresh(struct rpc_task *task) | |||
1257 | { | 1271 | { |
1258 | dprint_status(task); | 1272 | dprint_status(task); |
1259 | 1273 | ||
1260 | xprt_release(task); /* Must do to obtain new XID */ | ||
1261 | task->tk_action = call_refreshresult; | 1274 | task->tk_action = call_refreshresult; |
1262 | task->tk_status = 0; | 1275 | task->tk_status = 0; |
1263 | task->tk_client->cl_stats->rpcauthrefresh++; | 1276 | task->tk_client->cl_stats->rpcauthrefresh++; |
@@ -1375,6 +1388,8 @@ call_verify(struct rpc_task *task) | |||
1375 | dprintk("RPC: %5u %s: retry stale creds\n", | 1388 | dprintk("RPC: %5u %s: retry stale creds\n", |
1376 | task->tk_pid, __FUNCTION__); | 1389 | task->tk_pid, __FUNCTION__); |
1377 | rpcauth_invalcred(task); | 1390 | rpcauth_invalcred(task); |
1391 | /* Ensure we obtain a new XID! */ | ||
1392 | xprt_release(task); | ||
1378 | task->tk_action = call_refresh; | 1393 | task->tk_action = call_refresh; |
1379 | goto out_retry; | 1394 | goto out_retry; |
1380 | case RPC_AUTH_BADCRED: | 1395 | case RPC_AUTH_BADCRED: |
@@ -1523,13 +1538,18 @@ void rpc_show_tasks(void) | |||
1523 | spin_lock(&clnt->cl_lock); | 1538 | spin_lock(&clnt->cl_lock); |
1524 | list_for_each_entry(t, &clnt->cl_tasks, tk_task) { | 1539 | list_for_each_entry(t, &clnt->cl_tasks, tk_task) { |
1525 | const char *rpc_waitq = "none"; | 1540 | const char *rpc_waitq = "none"; |
1541 | int proc; | ||
1542 | |||
1543 | if (t->tk_msg.rpc_proc) | ||
1544 | proc = t->tk_msg.rpc_proc->p_proc; | ||
1545 | else | ||
1546 | proc = -1; | ||
1526 | 1547 | ||
1527 | if (RPC_IS_QUEUED(t)) | 1548 | if (RPC_IS_QUEUED(t)) |
1528 | rpc_waitq = rpc_qname(t->u.tk_wait.rpc_waitq); | 1549 | rpc_waitq = rpc_qname(t->u.tk_wait.rpc_waitq); |
1529 | 1550 | ||
1530 | printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n", | 1551 | printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n", |
1531 | t->tk_pid, | 1552 | t->tk_pid, proc, |
1532 | (t->tk_msg.rpc_proc ? t->tk_msg.rpc_proc->p_proc : -1), | ||
1533 | t->tk_flags, t->tk_status, | 1553 | t->tk_flags, t->tk_status, |
1534 | t->tk_client, | 1554 | t->tk_client, |
1535 | (t->tk_client ? t->tk_client->cl_prog : 0), | 1555 | (t->tk_client ? t->tk_client->cl_prog : 0), |