Message ID | 1470951574-18441-9-git-send-email-andros@netapp.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Hi Andy, On 08/11/2016 05:39 PM, andros@netapp.com wrote: > From: Andy Adamson <andros@netapp.com> > > Signed-off-by: Andy Adamson <andros@netapp.com> > --- > include/linux/sunrpc/clnt.h | 2 ++ > include/linux/sunrpc/xprtmultipath.h | 2 ++ > net/sunrpc/clnt.c | 15 +++++++++++++++ > net/sunrpc/xprtmultipath.c | 24 +++++++++++++++++++++++- > 4 files changed, 42 insertions(+), 1 deletion(-) > > diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h > index 28cbc81..2db687c 100644 > --- a/include/linux/sunrpc/clnt.h > +++ b/include/linux/sunrpc/clnt.h > @@ -200,5 +200,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_find_addr(struct rpc_clnt *clnt, > + const struct sockaddr *sap); > #endif /* __KERNEL__ */ > #endif /* _LINUX_SUNRPC_CLNT_H */ > diff --git a/include/linux/sunrpc/xprtmultipath.h b/include/linux/sunrpc/xprtmultipath.h > index 5a9acff..bc354bd 100644 > --- a/include/linux/sunrpc/xprtmultipath.h > +++ b/include/linux/sunrpc/xprtmultipath.h > @@ -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_find_addr(struct rpc_xprt_switch *xps, > + const struct sockaddr *sap); > #endif > diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c > index 35df635..e3cfced 100644 > --- a/net/sunrpc/clnt.c > +++ b/net/sunrpc/clnt.c > @@ -2685,6 +2685,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_find_addr(struct rpc_clnt *clnt, > + const struct sockaddr *sap) Since this is only returning a yes/no answer, can you rename it to rpc_clnt_xprt_switch_has_addr()? > +{ > + struct rpc_xprt_switch *xps; > + bool ret; > + > + xps = rcu_dereference(clnt->cl_xpi.xpi_xpswitch); > + > + rcu_read_lock(); > + ret = rpc_xprt_switch_find_addr(xps, sap); > + rcu_read_unlock(); > + return ret; > +} > +EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_find_addr); > + > #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) > static void rpc_show_header(void) > { > diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c > index 66c9d63..8798726 100644 > --- a/net/sunrpc/xprtmultipath.c > +++ b/net/sunrpc/xprtmultipath.c > @@ -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_find_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_find_addr(struct rpc_xprt_switch *xps, > + const struct sockaddr *sap) Same here: rpc_xprt_switch_has_addr() Thanks, Anna > +{ > + 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) > -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 28cbc81..2db687c 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -200,5 +200,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_find_addr(struct rpc_clnt *clnt, + const struct sockaddr *sap); #endif /* __KERNEL__ */ #endif /* _LINUX_SUNRPC_CLNT_H */ diff --git a/include/linux/sunrpc/xprtmultipath.h b/include/linux/sunrpc/xprtmultipath.h index 5a9acff..bc354bd 100644 --- a/include/linux/sunrpc/xprtmultipath.h +++ b/include/linux/sunrpc/xprtmultipath.h @@ -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_find_addr(struct rpc_xprt_switch *xps, + const struct sockaddr *sap); #endif diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 35df635..e3cfced 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -2685,6 +2685,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_find_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_find_addr(xps, sap); + rcu_read_unlock(); + return ret; +} +EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_find_addr); + #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) static void rpc_show_header(void) { diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c index 66c9d63..8798726 100644 --- a/net/sunrpc/xprtmultipath.c +++ b/net/sunrpc/xprtmultipath.c @@ -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_find_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_find_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)