diff mbox

[Version,8,08/12] SUNRPC search xprt switch for sockaddr

Message ID 1470951574-18441-9-git-send-email-andros@netapp.com (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Andy Adamson Aug. 11, 2016, 9:39 p.m. UTC
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(-)

Comments

Schumaker, Anna Aug. 12, 2016, 8:37 p.m. UTC | #1
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 mbox

Patch

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)