提交 ad01b2c6 编写于 作者: T Trond Myklebust

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: NTrond Myklebust <trond.myklebust@primarydata.com>
上级 80b14d5e
...@@ -25,6 +25,7 @@ ...@@ -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 { ...@@ -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 * ...@@ -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) ...@@ -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, ...@@ -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 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, ...@@ -438,6 +441,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
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, ...@@ -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); ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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 ...@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册