Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

SUNRPC search xprt switch for sockaddr

Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>

authored by

Andy Adamson and committed by
Anna Schumaker
39e5d2df dd691717

+42 -1
+2
include/linux/sunrpc/clnt.h
··· 202 202 203 203 void rpc_clnt_xprt_switch_put(struct rpc_clnt *); 204 204 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); 205 207 #endif /* __KERNEL__ */ 206 208 #endif /* _LINUX_SUNRPC_CLNT_H */
+2
include/linux/sunrpc/xprtmultipath.h
··· 66 66 extern struct rpc_xprt *xprt_iter_get_xprt(struct rpc_xprt_iter *xpi); 67 67 extern struct rpc_xprt *xprt_iter_get_next(struct rpc_xprt_iter *xpi); 68 68 69 + extern bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps, 70 + const struct sockaddr *sap); 69 71 #endif
+15
net/sunrpc/clnt.c
··· 2708 2708 } 2709 2709 EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_add_xprt); 2710 2710 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 + 2711 2726 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) 2712 2727 static void rpc_show_header(void) 2713 2728 {
+23 -1
net/sunrpc/xprtmultipath.c
··· 15 15 #include <asm/cmpxchg.h> 16 16 #include <linux/spinlock.h> 17 17 #include <linux/sunrpc/xprt.h> 18 + #include <linux/sunrpc/addr.h> 18 19 #include <linux/sunrpc/xprtmultipath.h> 19 20 20 21 typedef struct rpc_xprt *(*xprt_switch_find_xprt_t)(struct list_head *head, ··· 50 49 if (xprt == NULL) 51 50 return; 52 51 spin_lock(&xps->xps_lock); 53 - if (xps->xps_net == xprt->xprt_net || xps->xps_net == NULL) 52 + if ((xps->xps_net == xprt->xprt_net || xps->xps_net == NULL) && 53 + !rpc_xprt_switch_has_addr(xps, (struct sockaddr *)&xprt->addr)) 54 54 xprt_switch_add_xprt_locked(xps, xprt); 55 55 spin_unlock(&xps->xps_lock); 56 56 } ··· 232 230 if (xpi->xpi_cursor == NULL || xps->xps_nxprts < 2) 233 231 return xprt_switch_find_first_entry(head); 234 232 return xprt_switch_find_current_entry(head, xpi->xpi_cursor); 233 + } 234 + 235 + bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps, 236 + const struct sockaddr *sap) 237 + { 238 + struct list_head *head; 239 + struct rpc_xprt *pos; 240 + 241 + if (xps == NULL || sap == NULL) 242 + return false; 243 + 244 + head = &xps->xps_xprt_list; 245 + list_for_each_entry_rcu(pos, head, xprt_switch) { 246 + if (rpc_cmp_addr_port(sap, (struct sockaddr *)&pos->addr)) { 247 + pr_info("RPC: addr %s already in xprt switch\n", 248 + pos->address_strings[RPC_DISPLAY_ADDR]); 249 + return true; 250 + } 251 + } 252 + return false; 235 253 } 236 254 237 255 static