diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-01-30 14:17:26 -0500 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-02-05 18:48:54 -0500 |
commit | ad01b2c68d0ac5f3d4a3f807bec77b720b1c62a0 (patch) | |
tree | 1d4cfc7e222f9babf199bb7e5e67e8af90922a76 | |
parent | 80b14d5e61ca6d08e46b4fc72baf6e4f738b30ce (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.h | 2 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 4 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 32 | ||||
-rw-r--r-- | net/sunrpc/rpcb_clnt.c | 4 |
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 | ||
29 | struct rpc_inode; | 30 | struct 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 * | |||
1181 | gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) | 1181 | gss_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 | ||
356 | static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, | 356 | static 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: | |||
438 | out_err: | 441 | out_err: |
439 | rpciod_down(); | 442 | rpciod_down(); |
440 | out_no_rpciod: | 443 | out_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); | |||
564 | static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, | 573 | static 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 | ||
704 | out_revert: | 727 | out_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 | |||
648 | static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt) | 648 | static 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; |