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>
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
#include <asm/signal.h>
|
#include <asm/signal.h>
|
||||||
#include <linux/path.h>
|
#include <linux/path.h>
|
||||||
#include <net/ipv6.h>
|
#include <net/ipv6.h>
|
||||||
|
#include <linux/sunrpc/xprtmultipath.h>
|
||||||
|
|
||||||
struct rpc_inode;
|
struct rpc_inode;
|
||||||
|
|
||||||
@@ -67,6 +68,7 @@ struct rpc_clnt {
|
|||||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
struct dentry *cl_debugfs; /* debugfs directory */
|
struct dentry *cl_debugfs; /* debugfs directory */
|
||||||
#endif
|
#endif
|
||||||
|
struct rpc_xprt_iter cl_xpi;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1181,12 +1181,12 @@ static struct rpc_auth *
|
|||||||
gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
|
gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
|
||||||
{
|
{
|
||||||
struct gss_auth *gss_auth;
|
struct gss_auth *gss_auth;
|
||||||
struct rpc_xprt *xprt = rcu_access_pointer(clnt->cl_xprt);
|
struct rpc_xprt_switch *xps = rcu_access_pointer(clnt->cl_xpi.xpi_xpswitch);
|
||||||
|
|
||||||
while (clnt != clnt->cl_parent) {
|
while (clnt != clnt->cl_parent) {
|
||||||
struct rpc_clnt *parent = clnt->cl_parent;
|
struct rpc_clnt *parent = clnt->cl_parent;
|
||||||
/* Find the original parent for this transport */
|
/* Find the original parent for this transport */
|
||||||
if (rcu_access_pointer(parent->cl_xprt) != xprt)
|
if (rcu_access_pointer(parent->cl_xpi.xpi_xpswitch) != xps)
|
||||||
break;
|
break;
|
||||||
clnt = parent;
|
clnt = parent;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -354,6 +354,7 @@ static void rpc_free_clid(struct rpc_clnt *clnt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
|
static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
|
||||||
|
struct rpc_xprt_switch *xps,
|
||||||
struct rpc_xprt *xprt,
|
struct rpc_xprt *xprt,
|
||||||
struct rpc_clnt *parent)
|
struct rpc_clnt *parent)
|
||||||
{
|
{
|
||||||
@@ -411,6 +412,8 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rpc_clnt_set_transport(clnt, xprt, timeout);
|
rpc_clnt_set_transport(clnt, xprt, timeout);
|
||||||
|
xprt_iter_init(&clnt->cl_xpi, xps);
|
||||||
|
xprt_switch_put(xps);
|
||||||
|
|
||||||
clnt->cl_rtt = &clnt->cl_rtt_default;
|
clnt->cl_rtt = &clnt->cl_rtt_default;
|
||||||
rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval);
|
rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval);
|
||||||
@@ -438,6 +441,7 @@ out_no_clid:
|
|||||||
out_err:
|
out_err:
|
||||||
rpciod_down();
|
rpciod_down();
|
||||||
out_no_rpciod:
|
out_no_rpciod:
|
||||||
|
xprt_switch_put(xps);
|
||||||
xprt_put(xprt);
|
xprt_put(xprt);
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
@@ -446,8 +450,13 @@ struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
|
|||||||
struct rpc_xprt *xprt)
|
struct rpc_xprt *xprt)
|
||||||
{
|
{
|
||||||
struct rpc_clnt *clnt = NULL;
|
struct rpc_clnt *clnt = NULL;
|
||||||
|
struct rpc_xprt_switch *xps;
|
||||||
|
|
||||||
clnt = rpc_new_client(args, xprt, NULL);
|
xps = xprt_switch_alloc(xprt, GFP_KERNEL);
|
||||||
|
if (xps == NULL)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
clnt = rpc_new_client(args, xps, xprt, NULL);
|
||||||
if (IS_ERR(clnt))
|
if (IS_ERR(clnt))
|
||||||
return clnt;
|
return clnt;
|
||||||
|
|
||||||
@@ -564,6 +573,7 @@ EXPORT_SYMBOL_GPL(rpc_create);
|
|||||||
static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
|
static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
|
||||||
struct rpc_clnt *clnt)
|
struct rpc_clnt *clnt)
|
||||||
{
|
{
|
||||||
|
struct rpc_xprt_switch *xps;
|
||||||
struct rpc_xprt *xprt;
|
struct rpc_xprt *xprt;
|
||||||
struct rpc_clnt *new;
|
struct rpc_clnt *new;
|
||||||
int err;
|
int err;
|
||||||
@@ -571,13 +581,17 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
|
|||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
xprt = xprt_get(rcu_dereference(clnt->cl_xprt));
|
xprt = xprt_get(rcu_dereference(clnt->cl_xprt));
|
||||||
|
xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch));
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
if (xprt == NULL)
|
if (xprt == NULL || xps == NULL) {
|
||||||
|
xprt_put(xprt);
|
||||||
|
xprt_switch_put(xps);
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
}
|
||||||
args->servername = xprt->servername;
|
args->servername = xprt->servername;
|
||||||
args->nodename = clnt->cl_nodename;
|
args->nodename = clnt->cl_nodename;
|
||||||
|
|
||||||
new = rpc_new_client(args, xprt, clnt);
|
new = rpc_new_client(args, xps, xprt, clnt);
|
||||||
if (IS_ERR(new)) {
|
if (IS_ERR(new)) {
|
||||||
err = PTR_ERR(new);
|
err = PTR_ERR(new);
|
||||||
goto out_err;
|
goto out_err;
|
||||||
@@ -657,6 +671,7 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt,
|
|||||||
{
|
{
|
||||||
const struct rpc_timeout *old_timeo;
|
const struct rpc_timeout *old_timeo;
|
||||||
rpc_authflavor_t pseudoflavor;
|
rpc_authflavor_t pseudoflavor;
|
||||||
|
struct rpc_xprt_switch *xps, *oldxps;
|
||||||
struct rpc_xprt *xprt, *old;
|
struct rpc_xprt *xprt, *old;
|
||||||
struct rpc_clnt *parent;
|
struct rpc_clnt *parent;
|
||||||
int err;
|
int err;
|
||||||
@@ -668,10 +683,17 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt,
|
|||||||
return PTR_ERR(xprt);
|
return PTR_ERR(xprt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xps = xprt_switch_alloc(xprt, GFP_KERNEL);
|
||||||
|
if (xps == NULL) {
|
||||||
|
xprt_put(xprt);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
pseudoflavor = clnt->cl_auth->au_flavor;
|
pseudoflavor = clnt->cl_auth->au_flavor;
|
||||||
|
|
||||||
old_timeo = clnt->cl_timeout;
|
old_timeo = clnt->cl_timeout;
|
||||||
old = rpc_clnt_set_transport(clnt, xprt, timeout);
|
old = rpc_clnt_set_transport(clnt, xprt, timeout);
|
||||||
|
oldxps = xprt_iter_xchg_switch(&clnt->cl_xpi, xps);
|
||||||
|
|
||||||
rpc_unregister_client(clnt);
|
rpc_unregister_client(clnt);
|
||||||
__rpc_clnt_remove_pipedir(clnt);
|
__rpc_clnt_remove_pipedir(clnt);
|
||||||
@@ -697,14 +719,17 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt,
|
|||||||
synchronize_rcu();
|
synchronize_rcu();
|
||||||
if (parent != clnt)
|
if (parent != clnt)
|
||||||
rpc_release_client(parent);
|
rpc_release_client(parent);
|
||||||
|
xprt_switch_put(oldxps);
|
||||||
xprt_put(old);
|
xprt_put(old);
|
||||||
dprintk("RPC: replaced xprt for clnt %p\n", clnt);
|
dprintk("RPC: replaced xprt for clnt %p\n", clnt);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_revert:
|
out_revert:
|
||||||
|
xps = xprt_iter_xchg_switch(&clnt->cl_xpi, oldxps);
|
||||||
rpc_clnt_set_transport(clnt, old, old_timeo);
|
rpc_clnt_set_transport(clnt, old, old_timeo);
|
||||||
clnt->cl_parent = parent;
|
clnt->cl_parent = parent;
|
||||||
rpc_client_register(clnt, pseudoflavor, NULL);
|
rpc_client_register(clnt, pseudoflavor, NULL);
|
||||||
|
xprt_switch_put(xps);
|
||||||
xprt_put(xprt);
|
xprt_put(xprt);
|
||||||
dprintk("RPC: failed to switch xprt for clnt %p\n", clnt);
|
dprintk("RPC: failed to switch xprt for clnt %p\n", clnt);
|
||||||
return err;
|
return err;
|
||||||
@@ -783,6 +808,7 @@ rpc_free_client(struct rpc_clnt *clnt)
|
|||||||
rpc_free_iostats(clnt->cl_metrics);
|
rpc_free_iostats(clnt->cl_metrics);
|
||||||
clnt->cl_metrics = NULL;
|
clnt->cl_metrics = NULL;
|
||||||
xprt_put(rcu_dereference_raw(clnt->cl_xprt));
|
xprt_put(rcu_dereference_raw(clnt->cl_xprt));
|
||||||
|
xprt_iter_destroy(&clnt->cl_xpi);
|
||||||
rpciod_down();
|
rpciod_down();
|
||||||
rpc_free_clid(clnt);
|
rpc_free_clid(clnt);
|
||||||
kfree(clnt);
|
kfree(clnt);
|
||||||
|
|||||||
@@ -648,10 +648,10 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
|
|||||||
static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt)
|
static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt)
|
||||||
{
|
{
|
||||||
struct rpc_clnt *parent = clnt->cl_parent;
|
struct rpc_clnt *parent = clnt->cl_parent;
|
||||||
struct rpc_xprt *xprt = rcu_dereference(clnt->cl_xprt);
|
struct rpc_xprt_switch *xps = rcu_access_pointer(clnt->cl_xpi.xpi_xpswitch);
|
||||||
|
|
||||||
while (parent != clnt) {
|
while (parent != clnt) {
|
||||||
if (rcu_dereference(parent->cl_xprt) != xprt)
|
if (rcu_access_pointer(parent->cl_xpi.xpi_xpswitch) != xps)
|
||||||
break;
|
break;
|
||||||
if (clnt->cl_autobind)
|
if (clnt->cl_autobind)
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user