Skip to content

Commit 39e5d2d

Browse files
androsadamsonamschuma-ntap
authored andcommitted
SUNRPC search xprt switch for sockaddr
Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent dd69171 commit 39e5d2d

File tree

4 files changed

+42
-1
lines changed

4 files changed

+42
-1
lines changed

include/linux/sunrpc/clnt.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,5 +202,7 @@ const char *rpc_proc_name(const struct rpc_task *task);
202202

203203
void rpc_clnt_xprt_switch_put(struct rpc_clnt *);
204204
void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *, struct rpc_xprt *);
205+
bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
206+
const struct sockaddr *sap);
205207
#endif /* __KERNEL__ */
206208
#endif /* _LINUX_SUNRPC_CLNT_H */

include/linux/sunrpc/xprtmultipath.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,6 @@ extern struct rpc_xprt *xprt_iter_xprt(struct rpc_xprt_iter *xpi);
6666
extern struct rpc_xprt *xprt_iter_get_xprt(struct rpc_xprt_iter *xpi);
6767
extern struct rpc_xprt *xprt_iter_get_next(struct rpc_xprt_iter *xpi);
6868

69+
extern bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps,
70+
const struct sockaddr *sap);
6971
#endif

net/sunrpc/clnt.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2708,6 +2708,21 @@ void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt)
27082708
}
27092709
EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_add_xprt);
27102710

2711+
bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
2712+
const struct sockaddr *sap)
2713+
{
2714+
struct rpc_xprt_switch *xps;
2715+
bool ret;
2716+
2717+
xps = rcu_dereference(clnt->cl_xpi.xpi_xpswitch);
2718+
2719+
rcu_read_lock();
2720+
ret = rpc_xprt_switch_has_addr(xps, sap);
2721+
rcu_read_unlock();
2722+
return ret;
2723+
}
2724+
EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_has_addr);
2725+
27112726
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
27122727
static void rpc_show_header(void)
27132728
{

net/sunrpc/xprtmultipath.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <asm/cmpxchg.h>
1616
#include <linux/spinlock.h>
1717
#include <linux/sunrpc/xprt.h>
18+
#include <linux/sunrpc/addr.h>
1819
#include <linux/sunrpc/xprtmultipath.h>
1920

2021
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,
4950
if (xprt == NULL)
5051
return;
5152
spin_lock(&xps->xps_lock);
52-
if (xps->xps_net == xprt->xprt_net || xps->xps_net == NULL)
53+
if ((xps->xps_net == xprt->xprt_net || xps->xps_net == NULL) &&
54+
!rpc_xprt_switch_has_addr(xps, (struct sockaddr *)&xprt->addr))
5355
xprt_switch_add_xprt_locked(xps, xprt);
5456
spin_unlock(&xps->xps_lock);
5557
}
@@ -232,6 +234,26 @@ struct rpc_xprt *xprt_iter_current_entry(struct rpc_xprt_iter *xpi)
232234
return xprt_switch_find_current_entry(head, xpi->xpi_cursor);
233235
}
234236

237+
bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps,
238+
const struct sockaddr *sap)
239+
{
240+
struct list_head *head;
241+
struct rpc_xprt *pos;
242+
243+
if (xps == NULL || sap == NULL)
244+
return false;
245+
246+
head = &xps->xps_xprt_list;
247+
list_for_each_entry_rcu(pos, head, xprt_switch) {
248+
if (rpc_cmp_addr_port(sap, (struct sockaddr *)&pos->addr)) {
249+
pr_info("RPC: addr %s already in xprt switch\n",
250+
pos->address_strings[RPC_DISPLAY_ADDR]);
251+
return true;
252+
}
253+
}
254+
return false;
255+
}
256+
235257
static
236258
struct rpc_xprt *xprt_switch_find_next_entry(struct list_head *head,
237259
const struct rpc_xprt *cur)

0 commit comments

Comments
 (0)