Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 39e5d2df authored by Andy Adamson's avatar Andy Adamson Committed by Anna Schumaker
Browse files

SUNRPC search xprt switch for sockaddr

parent dd691717
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -202,5 +202,7 @@ const char *rpc_proc_name(const struct rpc_task *task);

void rpc_clnt_xprt_switch_put(struct rpc_clnt *);
void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *, struct rpc_xprt *);
bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
			const struct sockaddr *sap);
#endif /* __KERNEL__ */
#endif /* _LINUX_SUNRPC_CLNT_H */
+2 −0
Original line number Diff line number Diff line
@@ -66,4 +66,6 @@ extern struct rpc_xprt *xprt_iter_xprt(struct rpc_xprt_iter *xpi);
extern struct rpc_xprt *xprt_iter_get_xprt(struct rpc_xprt_iter *xpi);
extern struct rpc_xprt *xprt_iter_get_next(struct rpc_xprt_iter *xpi);

extern bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps,
		const struct sockaddr *sap);
#endif
+15 −0
Original line number Diff line number Diff line
@@ -2708,6 +2708,21 @@ void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt)
}
EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_add_xprt);

bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
				   const struct sockaddr *sap)
{
	struct rpc_xprt_switch *xps;
	bool ret;

	xps = rcu_dereference(clnt->cl_xpi.xpi_xpswitch);

	rcu_read_lock();
	ret = rpc_xprt_switch_has_addr(xps, sap);
	rcu_read_unlock();
	return ret;
}
EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_has_addr);

#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
static void rpc_show_header(void)
{
+23 −1
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <asm/cmpxchg.h>
#include <linux/spinlock.h>
#include <linux/sunrpc/xprt.h>
#include <linux/sunrpc/addr.h>
#include <linux/sunrpc/xprtmultipath.h>

typedef struct rpc_xprt *(*xprt_switch_find_xprt_t)(struct list_head *head,
@@ -49,7 +50,8 @@ void rpc_xprt_switch_add_xprt(struct rpc_xprt_switch *xps,
	if (xprt == NULL)
		return;
	spin_lock(&xps->xps_lock);
	if (xps->xps_net == xprt->xprt_net || xps->xps_net == NULL)
	if ((xps->xps_net == xprt->xprt_net || xps->xps_net == NULL) &&
	    !rpc_xprt_switch_has_addr(xps, (struct sockaddr *)&xprt->addr))
		xprt_switch_add_xprt_locked(xps, xprt);
	spin_unlock(&xps->xps_lock);
}
@@ -232,6 +234,26 @@ struct rpc_xprt *xprt_iter_current_entry(struct rpc_xprt_iter *xpi)
	return xprt_switch_find_current_entry(head, xpi->xpi_cursor);
}

bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps,
			      const struct sockaddr *sap)
{
	struct list_head *head;
	struct rpc_xprt *pos;

	if (xps == NULL || sap == NULL)
		return false;

	head = &xps->xps_xprt_list;
	list_for_each_entry_rcu(pos, head, xprt_switch) {
		if (rpc_cmp_addr_port(sap, (struct sockaddr *)&pos->addr)) {
			pr_info("RPC:   addr %s already in xprt switch\n",
				pos->address_strings[RPC_DISPLAY_ADDR]);
			return true;
		}
	}
	return false;
}

static
struct rpc_xprt *xprt_switch_find_next_entry(struct list_head *head,
		const struct rpc_xprt *cur)