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.c188
1 files changed, 113 insertions, 75 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 76be83ee4b04..924916ceaa43 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -30,6 +30,7 @@
30#include <linux/smp_lock.h> 30#include <linux/smp_lock.h>
31#include <linux/utsname.h> 31#include <linux/utsname.h>
32#include <linux/workqueue.h> 32#include <linux/workqueue.h>
33#include <linux/in6.h>
33 34
34#include <linux/sunrpc/clnt.h> 35#include <linux/sunrpc/clnt.h>
35#include <linux/sunrpc/rpc_pipe_fs.h> 36#include <linux/sunrpc/rpc_pipe_fs.h>
@@ -121,8 +122,9 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
121 } 122 }
122} 123}
123 124
124static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, struct rpc_program *program, u32 vers, rpc_authflavor_t flavor) 125static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
125{ 126{
127 struct rpc_program *program = args->program;
126 struct rpc_version *version; 128 struct rpc_version *version;
127 struct rpc_clnt *clnt = NULL; 129 struct rpc_clnt *clnt = NULL;
128 struct rpc_auth *auth; 130 struct rpc_auth *auth;
@@ -131,13 +133,13 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
131 133
132 /* sanity check the name before trying to print it */ 134 /* sanity check the name before trying to print it */
133 err = -EINVAL; 135 err = -EINVAL;
134 len = strlen(servname); 136 len = strlen(args->servername);
135 if (len > RPC_MAXNETNAMELEN) 137 if (len > RPC_MAXNETNAMELEN)
136 goto out_no_rpciod; 138 goto out_no_rpciod;
137 len++; 139 len++;
138 140
139 dprintk("RPC: creating %s client for %s (xprt %p)\n", 141 dprintk("RPC: creating %s client for %s (xprt %p)\n",
140 program->name, servname, xprt); 142 program->name, args->servername, xprt);
141 143
142 err = rpciod_up(); 144 err = rpciod_up();
143 if (err) 145 if (err)
@@ -145,7 +147,11 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
145 err = -EINVAL; 147 err = -EINVAL;
146 if (!xprt) 148 if (!xprt)
147 goto out_no_xprt; 149 goto out_no_xprt;
148 if (vers >= program->nrvers || !(version = program->version[vers])) 150
151 if (args->version >= program->nrvers)
152 goto out_err;
153 version = program->version[args->version];
154 if (version == NULL)
149 goto out_err; 155 goto out_err;
150 156
151 err = -ENOMEM; 157 err = -ENOMEM;
@@ -157,12 +163,12 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
157 clnt->cl_server = clnt->cl_inline_name; 163 clnt->cl_server = clnt->cl_inline_name;
158 if (len > sizeof(clnt->cl_inline_name)) { 164 if (len > sizeof(clnt->cl_inline_name)) {
159 char *buf = kmalloc(len, GFP_KERNEL); 165 char *buf = kmalloc(len, GFP_KERNEL);
160 if (buf != 0) 166 if (buf != NULL)
161 clnt->cl_server = buf; 167 clnt->cl_server = buf;
162 else 168 else
163 len = sizeof(clnt->cl_inline_name); 169 len = sizeof(clnt->cl_inline_name);
164 } 170 }
165 strlcpy(clnt->cl_server, servname, len); 171 strlcpy(clnt->cl_server, args->servername, len);
166 172
167 clnt->cl_xprt = xprt; 173 clnt->cl_xprt = xprt;
168 clnt->cl_procinfo = version->procs; 174 clnt->cl_procinfo = version->procs;
@@ -182,8 +188,15 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
182 if (!xprt_bound(clnt->cl_xprt)) 188 if (!xprt_bound(clnt->cl_xprt))
183 clnt->cl_autobind = 1; 189 clnt->cl_autobind = 1;
184 190
191 clnt->cl_timeout = xprt->timeout;
192 if (args->timeout != NULL) {
193 memcpy(&clnt->cl_timeout_default, args->timeout,
194 sizeof(clnt->cl_timeout_default));
195 clnt->cl_timeout = &clnt->cl_timeout_default;
196 }
197
185 clnt->cl_rtt = &clnt->cl_rtt_default; 198 clnt->cl_rtt = &clnt->cl_rtt_default;
186 rpc_init_rtt(&clnt->cl_rtt_default, xprt->timeout.to_initval); 199 rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval);
187 200
188 kref_init(&clnt->cl_kref); 201 kref_init(&clnt->cl_kref);
189 202
@@ -191,10 +204,10 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
191 if (err < 0) 204 if (err < 0)
192 goto out_no_path; 205 goto out_no_path;
193 206
194 auth = rpcauth_create(flavor, clnt); 207 auth = rpcauth_create(args->authflavor, clnt);
195 if (IS_ERR(auth)) { 208 if (IS_ERR(auth)) {
196 printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n", 209 printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n",
197 flavor); 210 args->authflavor);
198 err = PTR_ERR(auth); 211 err = PTR_ERR(auth);
199 goto out_no_auth; 212 goto out_no_auth;
200 } 213 }
@@ -245,9 +258,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
245 .srcaddr = args->saddress, 258 .srcaddr = args->saddress,
246 .dstaddr = args->address, 259 .dstaddr = args->address,
247 .addrlen = args->addrsize, 260 .addrlen = args->addrsize,
248 .timeout = args->timeout
249 }; 261 };
250 char servername[20]; 262 char servername[48];
251 263
252 xprt = xprt_create_transport(&xprtargs); 264 xprt = xprt_create_transport(&xprtargs);
253 if (IS_ERR(xprt)) 265 if (IS_ERR(xprt))
@@ -258,13 +270,34 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
258 * up a string representation of the passed-in address. 270 * up a string representation of the passed-in address.
259 */ 271 */
260 if (args->servername == NULL) { 272 if (args->servername == NULL) {
261 struct sockaddr_in *addr = 273 servername[0] = '\0';
262 (struct sockaddr_in *) args->address; 274 switch (args->address->sa_family) {
263 snprintf(servername, sizeof(servername), NIPQUAD_FMT, 275 case AF_INET: {
264 NIPQUAD(addr->sin_addr.s_addr)); 276 struct sockaddr_in *sin =
277 (struct sockaddr_in *)args->address;
278 snprintf(servername, sizeof(servername), NIPQUAD_FMT,
279 NIPQUAD(sin->sin_addr.s_addr));
280 break;
281 }
282 case AF_INET6: {
283 struct sockaddr_in6 *sin =
284 (struct sockaddr_in6 *)args->address;
285 snprintf(servername, sizeof(servername), NIP6_FMT,
286 NIP6(sin->sin6_addr));
287 break;
288 }
289 default:
290 /* caller wants default server name, but
291 * address family isn't recognized. */
292 return ERR_PTR(-EINVAL);
293 }
265 args->servername = servername; 294 args->servername = servername;
266 } 295 }
267 296
297 xprt = xprt_create_transport(&xprtargs);
298 if (IS_ERR(xprt))
299 return (struct rpc_clnt *)xprt;
300
268 /* 301 /*
269 * By default, kernel RPC client connects from a reserved port. 302 * By default, kernel RPC client connects from a reserved port.
270 * CAP_NET_BIND_SERVICE will not be set for unprivileged requesters, 303 * CAP_NET_BIND_SERVICE will not be set for unprivileged requesters,
@@ -275,8 +308,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
275 if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT) 308 if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT)
276 xprt->resvport = 0; 309 xprt->resvport = 0;
277 310
278 clnt = rpc_new_client(xprt, args->servername, args->program, 311 clnt = rpc_new_client(args, xprt);
279 args->version, args->authflavor);
280 if (IS_ERR(clnt)) 312 if (IS_ERR(clnt))
281 return clnt; 313 return clnt;
282 314
@@ -322,7 +354,7 @@ rpc_clone_client(struct rpc_clnt *clnt)
322 new->cl_autobind = 0; 354 new->cl_autobind = 0;
323 INIT_LIST_HEAD(&new->cl_tasks); 355 INIT_LIST_HEAD(&new->cl_tasks);
324 spin_lock_init(&new->cl_lock); 356 spin_lock_init(&new->cl_lock);
325 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); 357 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_timeout->to_initval);
326 new->cl_metrics = rpc_alloc_iostats(clnt); 358 new->cl_metrics = rpc_alloc_iostats(clnt);
327 if (new->cl_metrics == NULL) 359 if (new->cl_metrics == NULL)
328 goto out_no_stats; 360 goto out_no_stats;
@@ -345,6 +377,7 @@ out_no_clnt:
345 dprintk("RPC: %s: returned error %d\n", __FUNCTION__, err); 377 dprintk("RPC: %s: returned error %d\n", __FUNCTION__, err);
346 return ERR_PTR(err); 378 return ERR_PTR(err);
347} 379}
380EXPORT_SYMBOL_GPL(rpc_clone_client);
348 381
349/* 382/*
350 * Properly shut down an RPC client, terminating all outstanding 383 * Properly shut down an RPC client, terminating all outstanding
@@ -363,6 +396,7 @@ void rpc_shutdown_client(struct rpc_clnt *clnt)
363 396
364 rpc_release_client(clnt); 397 rpc_release_client(clnt);
365} 398}
399EXPORT_SYMBOL_GPL(rpc_shutdown_client);
366 400
367/* 401/*
368 * Free an RPC client 402 * Free an RPC client
@@ -467,6 +501,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
467out: 501out:
468 return clnt; 502 return clnt;
469} 503}
504EXPORT_SYMBOL_GPL(rpc_bind_new_program);
470 505
471/* 506/*
472 * Default callback for async RPC calls 507 * Default callback for async RPC calls
@@ -498,12 +533,12 @@ static void rpc_save_sigmask(sigset_t *oldset, int intr)
498 sigprocmask(SIG_BLOCK, &sigmask, oldset); 533 sigprocmask(SIG_BLOCK, &sigmask, oldset);
499} 534}
500 535
501static inline void rpc_task_sigmask(struct rpc_task *task, sigset_t *oldset) 536static void rpc_task_sigmask(struct rpc_task *task, sigset_t *oldset)
502{ 537{
503 rpc_save_sigmask(oldset, !RPC_TASK_UNINTERRUPTIBLE(task)); 538 rpc_save_sigmask(oldset, !RPC_TASK_UNINTERRUPTIBLE(task));
504} 539}
505 540
506static inline void rpc_restore_sigmask(sigset_t *oldset) 541static void rpc_restore_sigmask(sigset_t *oldset)
507{ 542{
508 sigprocmask(SIG_SETMASK, oldset, NULL); 543 sigprocmask(SIG_SETMASK, oldset, NULL);
509} 544}
@@ -512,45 +547,49 @@ void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset)
512{ 547{
513 rpc_save_sigmask(oldset, clnt->cl_intr); 548 rpc_save_sigmask(oldset, clnt->cl_intr);
514} 549}
550EXPORT_SYMBOL_GPL(rpc_clnt_sigmask);
515 551
516void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset) 552void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset)
517{ 553{
518 rpc_restore_sigmask(oldset); 554 rpc_restore_sigmask(oldset);
519} 555}
556EXPORT_SYMBOL_GPL(rpc_clnt_sigunmask);
520 557
521static 558/**
522struct rpc_task *rpc_do_run_task(struct rpc_clnt *clnt, 559 * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it
523 struct rpc_message *msg, 560 * @task_setup_data: pointer to task initialisation data
524 int flags, 561 */
525 const struct rpc_call_ops *ops, 562struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
526 void *data)
527{ 563{
528 struct rpc_task *task, *ret; 564 struct rpc_task *task, *ret;
529 sigset_t oldset; 565 sigset_t oldset;
530 566
531 task = rpc_new_task(clnt, flags, ops, data); 567 task = rpc_new_task(task_setup_data);
532 if (task == NULL) { 568 if (task == NULL) {
533 rpc_release_calldata(ops, data); 569 rpc_release_calldata(task_setup_data->callback_ops,
534 return ERR_PTR(-ENOMEM); 570 task_setup_data->callback_data);
571 ret = ERR_PTR(-ENOMEM);
572 goto out;
535 } 573 }
536 574
537 /* Mask signals on synchronous RPC calls and RPCSEC_GSS upcalls */ 575 if (task->tk_status != 0) {
538 rpc_task_sigmask(task, &oldset); 576 ret = ERR_PTR(task->tk_status);
539 if (msg != NULL) { 577 rpc_put_task(task);
540 rpc_call_setup(task, msg, 0); 578 goto out;
541 if (task->tk_status != 0) {
542 ret = ERR_PTR(task->tk_status);
543 rpc_put_task(task);
544 goto out;
545 }
546 } 579 }
547 atomic_inc(&task->tk_count); 580 atomic_inc(&task->tk_count);
548 rpc_execute(task); 581 /* Mask signals on synchronous RPC calls and RPCSEC_GSS upcalls */
582 if (!RPC_IS_ASYNC(task)) {
583 rpc_task_sigmask(task, &oldset);
584 rpc_execute(task);
585 rpc_restore_sigmask(&oldset);
586 } else
587 rpc_execute(task);
549 ret = task; 588 ret = task;
550out: 589out:
551 rpc_restore_sigmask(&oldset);
552 return ret; 590 return ret;
553} 591}
592EXPORT_SYMBOL_GPL(rpc_run_task);
554 593
555/** 594/**
556 * rpc_call_sync - Perform a synchronous RPC call 595 * rpc_call_sync - Perform a synchronous RPC call
@@ -561,17 +600,24 @@ out:
561int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) 600int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
562{ 601{
563 struct rpc_task *task; 602 struct rpc_task *task;
603 struct rpc_task_setup task_setup_data = {
604 .rpc_client = clnt,
605 .rpc_message = msg,
606 .callback_ops = &rpc_default_ops,
607 .flags = flags,
608 };
564 int status; 609 int status;
565 610
566 BUG_ON(flags & RPC_TASK_ASYNC); 611 BUG_ON(flags & RPC_TASK_ASYNC);
567 612
568 task = rpc_do_run_task(clnt, msg, flags, &rpc_default_ops, NULL); 613 task = rpc_run_task(&task_setup_data);
569 if (IS_ERR(task)) 614 if (IS_ERR(task))
570 return PTR_ERR(task); 615 return PTR_ERR(task);
571 status = task->tk_status; 616 status = task->tk_status;
572 rpc_put_task(task); 617 rpc_put_task(task);
573 return status; 618 return status;
574} 619}
620EXPORT_SYMBOL_GPL(rpc_call_sync);
575 621
576/** 622/**
577 * rpc_call_async - Perform an asynchronous RPC call 623 * rpc_call_async - Perform an asynchronous RPC call
@@ -586,45 +632,28 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
586 const struct rpc_call_ops *tk_ops, void *data) 632 const struct rpc_call_ops *tk_ops, void *data)
587{ 633{
588 struct rpc_task *task; 634 struct rpc_task *task;
635 struct rpc_task_setup task_setup_data = {
636 .rpc_client = clnt,
637 .rpc_message = msg,
638 .callback_ops = tk_ops,
639 .callback_data = data,
640 .flags = flags|RPC_TASK_ASYNC,
641 };
589 642
590 task = rpc_do_run_task(clnt, msg, flags|RPC_TASK_ASYNC, tk_ops, data); 643 task = rpc_run_task(&task_setup_data);
591 if (IS_ERR(task)) 644 if (IS_ERR(task))
592 return PTR_ERR(task); 645 return PTR_ERR(task);
593 rpc_put_task(task); 646 rpc_put_task(task);
594 return 0; 647 return 0;
595} 648}
596 649EXPORT_SYMBOL_GPL(rpc_call_async);
597/**
598 * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it
599 * @clnt: pointer to RPC client
600 * @flags: RPC flags
601 * @ops: RPC call ops
602 * @data: user call data
603 */
604struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
605 const struct rpc_call_ops *tk_ops,
606 void *data)
607{
608 return rpc_do_run_task(clnt, NULL, flags, tk_ops, data);
609}
610EXPORT_SYMBOL(rpc_run_task);
611 650
612void 651void
613rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags) 652rpc_call_start(struct rpc_task *task)
614{ 653{
615 task->tk_msg = *msg; 654 task->tk_action = call_start;
616 task->tk_flags |= flags;
617 /* Bind the user cred */
618 if (task->tk_msg.rpc_cred != NULL)
619 rpcauth_holdcred(task);
620 else
621 rpcauth_bindcred(task);
622
623 if (task->tk_status == 0)
624 task->tk_action = call_start;
625 else
626 task->tk_action = rpc_exit_task;
627} 655}
656EXPORT_SYMBOL_GPL(rpc_call_start);
628 657
629/** 658/**
630 * rpc_peeraddr - extract remote peer address from clnt's xprt 659 * rpc_peeraddr - extract remote peer address from clnt's xprt
@@ -653,7 +682,8 @@ EXPORT_SYMBOL_GPL(rpc_peeraddr);
653 * @format: address format 682 * @format: address format
654 * 683 *
655 */ 684 */
656char *rpc_peeraddr2str(struct rpc_clnt *clnt, enum rpc_display_format_t format) 685const char *rpc_peeraddr2str(struct rpc_clnt *clnt,
686 enum rpc_display_format_t format)
657{ 687{
658 struct rpc_xprt *xprt = clnt->cl_xprt; 688 struct rpc_xprt *xprt = clnt->cl_xprt;
659 689
@@ -671,6 +701,7 @@ rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize
671 if (xprt->ops->set_buffer_size) 701 if (xprt->ops->set_buffer_size)
672 xprt->ops->set_buffer_size(xprt, sndsize, rcvsize); 702 xprt->ops->set_buffer_size(xprt, sndsize, rcvsize);
673} 703}
704EXPORT_SYMBOL_GPL(rpc_setbufsize);
674 705
675/* 706/*
676 * Return size of largest payload RPC client can support, in bytes 707 * Return size of largest payload RPC client can support, in bytes
@@ -710,6 +741,7 @@ rpc_restart_call(struct rpc_task *task)
710 741
711 task->tk_action = call_start; 742 task->tk_action = call_start;
712} 743}
744EXPORT_SYMBOL_GPL(rpc_restart_call);
713 745
714/* 746/*
715 * 0. Initial state 747 * 0. Initial state
@@ -1137,7 +1169,7 @@ call_status(struct rpc_task *task)
1137 case -ETIMEDOUT: 1169 case -ETIMEDOUT:
1138 task->tk_action = call_timeout; 1170 task->tk_action = call_timeout;
1139 if (task->tk_client->cl_discrtry) 1171 if (task->tk_client->cl_discrtry)
1140 xprt_disconnect(task->tk_xprt); 1172 xprt_force_disconnect(task->tk_xprt);
1141 break; 1173 break;
1142 case -ECONNREFUSED: 1174 case -ECONNREFUSED:
1143 case -ENOTCONN: 1175 case -ENOTCONN:
@@ -1260,7 +1292,7 @@ out_retry:
1260 req->rq_received = req->rq_private_buf.len = 0; 1292 req->rq_received = req->rq_private_buf.len = 0;
1261 task->tk_status = 0; 1293 task->tk_status = 0;
1262 if (task->tk_client->cl_discrtry) 1294 if (task->tk_client->cl_discrtry)
1263 xprt_disconnect(task->tk_xprt); 1295 xprt_force_disconnect(task->tk_xprt);
1264} 1296}
1265 1297
1266/* 1298/*
@@ -1517,9 +1549,15 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int
1517 .rpc_proc = &rpcproc_null, 1549 .rpc_proc = &rpcproc_null,
1518 .rpc_cred = cred, 1550 .rpc_cred = cred,
1519 }; 1551 };
1520 return rpc_do_run_task(clnt, &msg, flags, &rpc_default_ops, NULL); 1552 struct rpc_task_setup task_setup_data = {
1553 .rpc_client = clnt,
1554 .rpc_message = &msg,
1555 .callback_ops = &rpc_default_ops,
1556 .flags = flags,
1557 };
1558 return rpc_run_task(&task_setup_data);
1521} 1559}
1522EXPORT_SYMBOL(rpc_call_null); 1560EXPORT_SYMBOL_GPL(rpc_call_null);
1523 1561
1524#ifdef RPC_DEBUG 1562#ifdef RPC_DEBUG
1525void rpc_show_tasks(void) 1563void rpc_show_tasks(void)