This change of API allows adding transports without holding a reference to an rpc client. Signed-off-by: Dan Aloni <dan@xxxxxxxxxxxx> --- fs/nfs/pnfs_nfs.c | 12 +++++++----- include/linux/sunrpc/clnt.h | 12 +++++++----- net/sunrpc/clnt.c | 31 +++++++++++++++++-------------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index 49d3389bd813..1e61626bd0fa 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c @@ -878,8 +878,9 @@ static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv, if (da->da_addr.ss_family != clp->cl_addr.ss_family) continue; /* Add this address as an alias */ - rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args, - rpc_clnt_test_and_add_xprt, NULL); + rpc_add_xprt(&clp->cl_rpcclient->cl_xpi, + clp->cl_rpcclient, &xprt_args, + rpc_clnt_test_and_add_xprt, NULL); continue; } clp = get_v3_ds_connect(mds_srv, @@ -945,9 +946,10 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv, * add as an alias */ xprtdata.cred = nfs4_get_clid_cred(clp), - rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args, - rpc_clnt_setup_test_and_add_xprt, - &rpcdata); + rpc_add_xprt(&clp->cl_rpcclient->cl_xpi, + clp->cl_rpcclient, &xprt_args, + rpc_clnt_setup_test_and_add_xprt, + &rpcdata); if (xprtdata.cred) put_cred(xprtdata.cred); } else { diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 503653720e18..19bb23143eef 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -210,21 +210,23 @@ int rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt, int (*fn)(struct rpc_clnt *, struct rpc_xprt *, void *), void *data); -int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt, +int rpc_clnt_test_and_add_xprt(void *clnt, struct rpc_xprt_switch *xps, struct rpc_xprt *xprt, void *dummy); -int rpc_clnt_add_xprt(struct rpc_clnt *, struct xprt_create *, - int (*setup)(struct rpc_clnt *, +int rpc_add_xprt(struct rpc_xprt_iter *iter, + void *ctx, + struct xprt_create *xprtargs, + int (*setup)(void *ctx, struct rpc_xprt_switch *, struct rpc_xprt *, void *), - void *data); + void *data); void rpc_set_connect_timeout(struct rpc_clnt *clnt, unsigned long connect_timeout, unsigned long reconnect_timeout); -int rpc_clnt_setup_test_and_add_xprt(struct rpc_clnt *, +int rpc_clnt_setup_test_and_add_xprt(void *, struct rpc_xprt_switch *, struct rpc_xprt *, void *); diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 0a4811be01cd..b94d274a5446 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -598,7 +598,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) return clnt; for (i = 0; i < args->nconnect - 1; i++) { - if (rpc_clnt_add_xprt(clnt, &xprtargs, NULL, NULL) < 0) + if (rpc_add_xprt(&clnt->cl_xpi, NULL, &xprtargs, NULL, NULL) < 0) break; } return clnt; @@ -2751,10 +2751,11 @@ static const struct rpc_call_ops rpc_cb_add_xprt_call_ops = { * @xprt: pointer struct rpc_xprt * @dummy: unused */ -int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt, +int rpc_clnt_test_and_add_xprt(void *ptr, struct rpc_xprt_switch *xps, struct rpc_xprt *xprt, void *dummy) { + struct rpc_clnt *clnt = ptr; struct rpc_cb_add_xprt_calldata *data; struct rpc_task *task; @@ -2795,11 +2796,12 @@ EXPORT_SYMBOL_GPL(rpc_clnt_test_and_add_xprt); * @data: a struct rpc_add_xprt_test pointer that holds the test function * and test function call data */ -int rpc_clnt_setup_test_and_add_xprt(struct rpc_clnt *clnt, +int rpc_clnt_setup_test_and_add_xprt(void *ptr, struct rpc_xprt_switch *xps, struct rpc_xprt *xprt, void *data) { + struct rpc_clnt *clnt = ptr; struct rpc_task *task; struct rpc_add_xprt_test *xtest = (struct rpc_add_xprt_test *)data; int status = -EADDRINUSE; @@ -2852,13 +2854,14 @@ EXPORT_SYMBOL_GPL(rpc_clnt_setup_test_and_add_xprt); * adding the new transport. * */ -int rpc_clnt_add_xprt(struct rpc_clnt *clnt, - struct xprt_create *xprtargs, - int (*setup)(struct rpc_clnt *, - struct rpc_xprt_switch *, - struct rpc_xprt *, - void *), - void *data) +int rpc_add_xprt(struct rpc_xprt_iter *iter, + void *ctx, + struct xprt_create *xprtargs, + int (*setup)(void *ctx, + struct rpc_xprt_switch *, + struct rpc_xprt *, + void *), + void *data) { struct rpc_xprt_switch *xps; struct rpc_xprt *xprt; @@ -2868,8 +2871,8 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt, int ret = 0; rcu_read_lock(); - xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch)); - xprt = xprt_iter_xprt(&clnt->cl_xpi); + xps = xprt_switch_get(rcu_dereference(iter->xpi_xpswitch)); + xprt = xprt_iter_xprt(iter); if (xps == NULL || xprt == NULL) { rcu_read_unlock(); xprt_switch_put(xps); @@ -2895,7 +2898,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt, rpc_xprt_switch_set_roundrobin(xps); if (setup) { - ret = setup(clnt, xps, xprt, data); + ret = setup(ctx, xps, xprt, data); if (ret != 0) goto out_put_xprt; } @@ -2906,7 +2909,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt, xprt_switch_put(xps); return ret; } -EXPORT_SYMBOL_GPL(rpc_clnt_add_xprt); +EXPORT_SYMBOL_GPL(rpc_add_xprt); struct connect_timeout_data { unsigned long connect_timeout; -- 2.26.2