aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-01-30 14:17:26 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2016-02-05 18:48:54 -0500
commitad01b2c68d0ac5f3d4a3f807bec77b720b1c62a0 (patch)
tree1d4cfc7e222f9babf199bb7e5e67e8af90922a76
parent80b14d5e61ca6d08e46b4fc72baf6e4f738b30ce (diff)
SUNRPC: Make rpc_clnt store the multipath iterators
This is a pre-patch for the RPC multipath code. It sets up the storage in struct rpc_clnt for the multipath code. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r--include/linux/sunrpc/clnt.h2
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c4
-rw-r--r--net/sunrpc/clnt.c32
-rw-r--r--net/sunrpc/rpcb_clnt.c4
4 files changed, 35 insertions, 7 deletions
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 0c5c2cbe96c9..1713e41d65ae 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -25,6 +25,7 @@
25#include <asm/signal.h> 25#include <asm/signal.h>
26#include <linux/path.h> 26#include <linux/path.h>
27#include <net/ipv6.h> 27#include <net/ipv6.h>
28#include <linux/sunrpc/xprtmultipath.h>
28 29
29struct rpc_inode; 30struct rpc_inode;
30 31
@@ -67,6 +68,7 @@ struct rpc_clnt {
67#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) 68#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
68 struct dentry *cl_debugfs; /* debugfs directory */ 69 struct dentry *cl_debugfs; /* debugfs directory */
69#endif 70#endif
71 struct rpc_xprt_iter cl_xpi;
70}; 72};
71 73
72/* 74/*
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 799e65b944b9..3ce391cb80c4 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -1181,12 +1181,12 @@ static struct rpc_auth *
1181gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) 1181gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
1182{ 1182{
1183 struct gss_auth *gss_auth; 1183 struct gss_auth *gss_auth;
1184 struct rpc_xprt *xprt = rcu_access_pointer(clnt->cl_xprt); 1184 struct rpc_xprt_switch *xps = rcu_access_pointer(clnt->cl_xpi.xpi_xpswitch);
1185 1185
1186 while (clnt != clnt->cl_parent) { 1186 while (clnt != clnt->cl_parent) {
1187 struct rpc_clnt *parent = clnt->cl_parent; 1187 struct rpc_clnt *parent = clnt->cl_parent;
1188 /* Find the original parent for this transport */ 1188 /* Find the original parent for this transport */
1189 if (rcu_access_pointer(parent->cl_xprt) != xprt) 1189 if (rcu_access_pointer(parent->cl_xpi.xpi_xpswitch) != xps)
1190 break; 1190 break;
1191 clnt = parent; 1191 clnt = parent;
1192 } 1192 }
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 2b4ad7aa40c6..625fb8a184c6 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -354,6 +354,7 @@ static void rpc_free_clid(struct rpc_clnt *clnt)
354} 354}
355 355
356static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, 356static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
357 struct rpc_xprt_switch *xps,
357 struct rpc_xprt *xprt, 358 struct rpc_xprt *xprt,
358 struct rpc_clnt *parent) 359 struct rpc_clnt *parent)
359{ 360{
@@ -411,6 +412,8 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
411 } 412 }
412 413
413 rpc_clnt_set_transport(clnt, xprt, timeout); 414 rpc_clnt_set_transport(clnt, xprt, timeout);
415 xprt_iter_init(&clnt->cl_xpi, xps);
416 xprt_switch_put(xps);
414 417
415 clnt->cl_rtt = &clnt->cl_rtt_default; 418 clnt->cl_rtt = &clnt->cl_rtt_default;
416 rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval); 419 rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval);
@@ -438,6 +441,7 @@ out_no_clid:
438out_err: 441out_err:
439 rpciod_down(); 442 rpciod_down();
440out_no_rpciod: 443out_no_rpciod:
444 xprt_switch_put(xps);
441 xprt_put(xprt); 445 xprt_put(xprt);
442 return ERR_PTR(err); 446 return ERR_PTR(err);
443} 447}
@@ -446,8 +450,13 @@ struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
446 struct rpc_xprt *xprt) 450 struct rpc_xprt *xprt)
447{ 451{
448 struct rpc_clnt *clnt = NULL; 452 struct rpc_clnt *clnt = NULL;
453 struct rpc_xprt_switch *xps;
449 454
450 clnt = rpc_new_client(args, xprt, NULL); 455 xps = xprt_switch_alloc(xprt, GFP_KERNEL);
456 if (xps == NULL)
457 return ERR_PTR(-ENOMEM);
458
459 clnt = rpc_new_client(args, xps, xprt, NULL);
451 if (IS_ERR(clnt)) 460 if (IS_ERR(clnt))
452 return clnt; 461 return clnt;
453 462
@@ -564,6 +573,7 @@ EXPORT_SYMBOL_GPL(rpc_create);
564static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, 573static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
565 struct rpc_clnt *clnt) 574 struct rpc_clnt *clnt)
566{ 575{
576 struct rpc_xprt_switch *xps;
567 struct rpc_xprt *xprt; 577 struct rpc_xprt *xprt;
568 struct rpc_clnt *new; 578 struct rpc_clnt *new;
569 int err; 579 int err;
@@ -571,13 +581,17 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
571 err = -ENOMEM; 581 err = -ENOMEM;
572 rcu_read_lock(); 582 rcu_read_lock();
573 xprt = xprt_get(rcu_dereference(clnt->cl_xprt)); 583 xprt = xprt_get(rcu_dereference(clnt->cl_xprt));
584 xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch));
574 rcu_read_unlock(); 585 rcu_read_unlock();
575 if (xprt == NULL) 586 if (xprt == NULL || xps == NULL) {
587 xprt_put(xprt);
588 xprt_switch_put(xps);
576 goto out_err; 589 goto out_err;
590 }
577 args->servername = xprt->servername; 591 args->servername = xprt->servername;
578 args->nodename = clnt->cl_nodename; 592 args->nodename = clnt->cl_nodename;
579 593
580 new = rpc_new_client(args, xprt, clnt); 594 new = rpc_new_client(args, xps, xprt, clnt);
581 if (IS_ERR(new)) { 595 if (IS_ERR(new)) {
582 err = PTR_ERR(new); 596 err = PTR_ERR(new);
583 goto out_err; 597 goto out_err;
@@ -657,6 +671,7 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt,
657{ 671{
658 const struct rpc_timeout *old_timeo; 672 const struct rpc_timeout *old_timeo;
659 rpc_authflavor_t pseudoflavor; 673 rpc_authflavor_t pseudoflavor;
674 struct rpc_xprt_switch *xps, *oldxps;
660 struct rpc_xprt *xprt, *old; 675 struct rpc_xprt *xprt, *old;
661 struct rpc_clnt *parent; 676 struct rpc_clnt *parent;
662 int err; 677 int err;
@@ -668,10 +683,17 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt,
668 return PTR_ERR(xprt); 683 return PTR_ERR(xprt);
669 } 684 }
670 685
686 xps = xprt_switch_alloc(xprt, GFP_KERNEL);
687 if (xps == NULL) {
688 xprt_put(xprt);
689 return -ENOMEM;
690 }
691
671 pseudoflavor = clnt->cl_auth->au_flavor; 692 pseudoflavor = clnt->cl_auth->au_flavor;
672 693
673 old_timeo = clnt->cl_timeout; 694 old_timeo = clnt->cl_timeout;
674 old = rpc_clnt_set_transport(clnt, xprt, timeout); 695 old = rpc_clnt_set_transport(clnt, xprt, timeout);
696 oldxps = xprt_iter_xchg_switch(&clnt->cl_xpi, xps);
675 697
676 rpc_unregister_client(clnt); 698 rpc_unregister_client(clnt);
677 __rpc_clnt_remove_pipedir(clnt); 699 __rpc_clnt_remove_pipedir(clnt);
@@ -697,14 +719,17 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt,
697 synchronize_rcu(); 719 synchronize_rcu();
698 if (parent != clnt) 720 if (parent != clnt)
699 rpc_release_client(parent); 721 rpc_release_client(parent);
722 xprt_switch_put(oldxps);
700 xprt_put(old); 723 xprt_put(old);
701 dprintk("RPC: replaced xprt for clnt %p\n", clnt); 724 dprintk("RPC: replaced xprt for clnt %p\n", clnt);
702 return 0; 725 return 0;
703 726
704out_revert: 727out_revert:
728 xps = xprt_iter_xchg_switch(&clnt->cl_xpi, oldxps);
705 rpc_clnt_set_transport(clnt, old, old_timeo); 729 rpc_clnt_set_transport(clnt, old, old_timeo);
706 clnt->cl_parent = parent; 730 clnt->cl_parent = parent;
707 rpc_client_register(clnt, pseudoflavor, NULL); 731 rpc_client_register(clnt, pseudoflavor, NULL);
732 xprt_switch_put(xps);
708 xprt_put(xprt); 733 xprt_put(xprt);
709 dprintk("RPC: failed to switch xprt for clnt %p\n", clnt); 734 dprintk("RPC: failed to switch xprt for clnt %p\n", clnt);
710 return err; 735 return err;
@@ -783,6 +808,7 @@ rpc_free_client(struct rpc_clnt *clnt)
783 rpc_free_iostats(clnt->cl_metrics); 808 rpc_free_iostats(clnt->cl_metrics);
784 clnt->cl_metrics = NULL; 809 clnt->cl_metrics = NULL;
785 xprt_put(rcu_dereference_raw(clnt->cl_xprt)); 810 xprt_put(rcu_dereference_raw(clnt->cl_xprt));
811 xprt_iter_destroy(&clnt->cl_xpi);
786 rpciod_down(); 812 rpciod_down();
787 rpc_free_clid(clnt); 813 rpc_free_clid(clnt);
788 kfree(clnt); 814 kfree(clnt);
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index cf5770d8f49a..44f025c150d8 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -648,10 +648,10 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
648static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt) 648static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt)
649{ 649{
650 struct rpc_clnt *parent = clnt->cl_parent; 650 struct rpc_clnt *parent = clnt->cl_parent;
651 struct rpc_xprt *xprt = rcu_dereference(clnt->cl_xprt); 651 struct rpc_xprt_switch *xps = rcu_access_pointer(clnt->cl_xpi.xpi_xpswitch);
652 652
653 while (parent != clnt) { 653 while (parent != clnt) {
654 if (rcu_dereference(parent->cl_xprt) != xprt) 654 if (rcu_access_pointer(parent->cl_xpi.xpi_xpswitch) != xps)
655 break; 655 break;
656 if (clnt->cl_autobind) 656 if (clnt->cl_autobind)
657 break; 657 break;