Skip to content

Commit 3227886

Browse files
committed
SUNRPC: Add a helper to apply a function to all the rpc_clnt's transports
Add a helper for tasks that require us to apply a function to all the transports in an rpc_clnt. An example of a usecase would be BIND_CONN_TO_SESSION, where we want to send one RPC call down each transport. Signed-off-by: Trond Myklebust <[email protected]>
1 parent 9d61498 commit 3227886

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

include/linux/sunrpc/clnt.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
182182
const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
183183
int rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t);
184184

185+
int rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt,
186+
int (*fn)(struct rpc_clnt *, struct rpc_xprt *, void *),
187+
void *data);
188+
185189
const char *rpc_proc_name(const struct rpc_task *task);
186190
#endif /* __KERNEL__ */
187191
#endif /* _LINUX_SUNRPC_CLNT_H */

net/sunrpc/clnt.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,57 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt,
736736
}
737737
EXPORT_SYMBOL_GPL(rpc_switch_client_transport);
738738

739+
static
740+
int rpc_clnt_xprt_iter_init(struct rpc_clnt *clnt, struct rpc_xprt_iter *xpi)
741+
{
742+
struct rpc_xprt_switch *xps;
743+
744+
rcu_read_lock();
745+
xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch));
746+
rcu_read_unlock();
747+
if (xps == NULL)
748+
return -EAGAIN;
749+
xprt_iter_init_listall(xpi, xps);
750+
xprt_switch_put(xps);
751+
return 0;
752+
}
753+
754+
/**
755+
* rpc_clnt_iterate_for_each_xprt - Apply a function to all transports
756+
* @clnt: pointer to client
757+
* @fn: function to apply
758+
* @data: void pointer to function data
759+
*
760+
* Iterates through the list of RPC transports currently attached to the
761+
* client and applies the function fn(clnt, xprt, data).
762+
*
763+
* On error, the iteration stops, and the function returns the error value.
764+
*/
765+
int rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt,
766+
int (*fn)(struct rpc_clnt *, struct rpc_xprt *, void *),
767+
void *data)
768+
{
769+
struct rpc_xprt_iter xpi;
770+
int ret;
771+
772+
ret = rpc_clnt_xprt_iter_init(clnt, &xpi);
773+
if (ret)
774+
return ret;
775+
for (;;) {
776+
struct rpc_xprt *xprt = xprt_iter_get_next(&xpi);
777+
778+
if (!xprt)
779+
break;
780+
ret = fn(clnt, xprt, data);
781+
xprt_put(xprt);
782+
if (ret < 0)
783+
break;
784+
}
785+
xprt_iter_destroy(&xpi);
786+
return ret;
787+
}
788+
EXPORT_SYMBOL_GPL(rpc_clnt_iterate_for_each_xprt);
789+
739790
/*
740791
* Kill all tasks for the given client.
741792
* XXX: kill their descendants as well?

0 commit comments

Comments
 (0)