]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
SUNRPC: Add a helper to apply a function to all the rpc_clnt's transports
authorTrond Myklebust <trond.myklebust@primarydata.com>
Sun, 31 Jan 2016 01:39:19 +0000 (20:39 -0500)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Fri, 5 Feb 2016 23:48:55 +0000 (18:48 -0500)
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 <trond.myklebust@primarydata.com>
include/linux/sunrpc/clnt.h
net/sunrpc/clnt.c

index 1713e41d65ae279f8ba8476d31346b13706ac42e..d6510f64a361d5601c344b99bba38d8357db729a 100644 (file)
@@ -182,6 +182,10 @@ size_t             rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
 const char     *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
 int            rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t);
 
+int            rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt,
+                       int (*fn)(struct rpc_clnt *, struct rpc_xprt *, void *),
+                       void *data);
+
 const char *rpc_proc_name(const struct rpc_task *task);
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SUNRPC_CLNT_H */
index 8e46fa5a2ab114efd34cc09f22b71ff661f314bb..19feb4d5d79628a0917a2811993d09bf6f83281a 100644 (file)
@@ -736,6 +736,57 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt,
 }
 EXPORT_SYMBOL_GPL(rpc_switch_client_transport);
 
+static
+int rpc_clnt_xprt_iter_init(struct rpc_clnt *clnt, struct rpc_xprt_iter *xpi)
+{
+       struct rpc_xprt_switch *xps;
+
+       rcu_read_lock();
+       xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch));
+       rcu_read_unlock();
+       if (xps == NULL)
+               return -EAGAIN;
+       xprt_iter_init_listall(xpi, xps);
+       xprt_switch_put(xps);
+       return 0;
+}
+
+/**
+ * rpc_clnt_iterate_for_each_xprt - Apply a function to all transports
+ * @clnt: pointer to client
+ * @fn: function to apply
+ * @data: void pointer to function data
+ *
+ * Iterates through the list of RPC transports currently attached to the
+ * client and applies the function fn(clnt, xprt, data).
+ *
+ * On error, the iteration stops, and the function returns the error value.
+ */
+int rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt,
+               int (*fn)(struct rpc_clnt *, struct rpc_xprt *, void *),
+               void *data)
+{
+       struct rpc_xprt_iter xpi;
+       int ret;
+
+       ret = rpc_clnt_xprt_iter_init(clnt, &xpi);
+       if (ret)
+               return ret;
+       for (;;) {
+               struct rpc_xprt *xprt = xprt_iter_get_next(&xpi);
+
+               if (!xprt)
+                       break;
+               ret = fn(clnt, xprt, data);
+               xprt_put(xprt);
+               if (ret < 0)
+                       break;
+       }
+       xprt_iter_destroy(&xpi);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(rpc_clnt_iterate_for_each_xprt);
+
 /*
  * Kill all tasks for the given client.
  * XXX: kill their descendants as well?