diff mbox series

[v1,11/12] SUNRPC create a function that probes only offline transports

Message ID 20220620152407.63127-12-olga.kornievskaia@gmail.com (mailing list archive)
State New, archived
Headers show
Series Handling session trunking group membership | expand

Commit Message

Olga Kornievskaia June 20, 2022, 3:24 p.m. UTC
From: Olga Kornievskaia <kolga@netapp.com>

For only offline transports, attempt to check connectivity via
a NULL call and, if that succeeds, call a provided session trunking
detection function.

Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
---
 fs/nfs/nfs4proc.c           |  2 +-
 include/linux/sunrpc/clnt.h |  3 ++-
 net/sunrpc/clnt.c           | 47 +++++++++++++++++++++++++++++++++----
 net/sunrpc/debugfs.c        |  3 ++-
 net/sunrpc/stats.c          |  2 +-
 5 files changed, 48 insertions(+), 9 deletions(-)

Comments

Trond Myklebust July 12, 2022, 4 p.m. UTC | #1
On Mon, 2022-06-20 at 11:24 -0400, Olga Kornievskaia wrote:
> From: Olga Kornievskaia <kolga@netapp.com>
> 
> For only offline transports, attempt to check connectivity via
> a NULL call and, if that succeeds, call a provided session trunking
> detection function.
> 
> Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
> ---
>  fs/nfs/nfs4proc.c           |  2 +-
>  include/linux/sunrpc/clnt.h |  3 ++-
>  net/sunrpc/clnt.c           | 47 +++++++++++++++++++++++++++++++++--
> --
>  net/sunrpc/debugfs.c        |  3 ++-
>  net/sunrpc/stats.c          |  2 +-
>  5 files changed, 48 insertions(+), 9 deletions(-)
> 
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index 152da2bc5100..00778f351283 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -8533,7 +8533,7 @@ int nfs4_proc_bind_conn_to_session(struct
> nfs_client *clp, const struct cred *cr
>                 .cred = cred,
>         };
>         return rpc_clnt_iterate_for_each_xprt(clp->cl_rpcclient,
> NULL,
> -                       nfs4_proc_bind_conn_to_session_callback,
> &data);
> +                       nfs4_proc_bind_conn_to_session_callback,
> &data, false);
>  }
>  
>  /*
> diff --git a/include/linux/sunrpc/clnt.h
> b/include/linux/sunrpc/clnt.h
> index ac1024da86c5..a0160b83d4a4 100644
> --- a/include/linux/sunrpc/clnt.h
> +++ b/include/linux/sunrpc/clnt.h
> @@ -215,7 +215,7 @@ int         rpc_localaddr(struct rpc_clnt *,
> struct sockaddr *, size_t);
>  int            rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt,
>                         int (*setup)(struct rpc_clnt *, struct
> rpc_xprt_iter *),
>                         int (*fn)(struct rpc_clnt *, struct rpc_xprt
> *, void *),
> -                       void *data);
> +                       void *data, bool do_rewind);
>  
>  int            rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt,
>                         struct rpc_xprt_switch *xps,
> @@ -236,6 +236,7 @@
> int         rpc_clnt_setup_test_and_add_xprt(struct rpc_clnt *,
>                         struct rpc_xprt *,
>                         void *);
>  void           rpc_clnt_manage_trunked_xprts(struct rpc_clnt *, void
> *);
> +void           rpc_probe_trunked_xprts(struct rpc_clnt *, void *);
>  
>  const char *rpc_proc_name(const struct rpc_task *task);
>  
> diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
> index 6b04b29bf842..348d0772c91d 100644
> --- a/net/sunrpc/clnt.c
> +++ b/net/sunrpc/clnt.c
> @@ -830,7 +830,7 @@ int rpc_clnt_xprt_iter_offline_init(struct
> rpc_clnt *clnt,
>  int rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt,
>                 int (*setup)(struct rpc_clnt *, struct rpc_xprt_iter
> *),
>                 int (*fn)(struct rpc_clnt *, struct rpc_xprt *, void
> *),
> -               void *data)
> +               void *data, bool do_rewind)
>  {
>         struct rpc_xprt_iter xpi;
>         int ret;
> @@ -850,6 +850,9 @@ int rpc_clnt_iterate_for_each_xprt(struct
> rpc_clnt *clnt,
>                 xprt_put(xprt);
>                 if (ret < 0)
>                         break;
> +
> +               if (do_rewind)
> +                       xprt_iter_rewind(&xpi);

This really needs to be another separate function. You are not
iterating over each xprt here, you are always looking at the first
valid entry.

>         }
>         xprt_iter_destroy(&xpi);
>         return ret;
> @@ -3032,6 +3035,40 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
>  }
>  EXPORT_SYMBOL_GPL(rpc_clnt_add_xprt);
>  
> +static int rpc_xprt_probe_trunked(struct rpc_clnt *clnt,
> +                                 struct rpc_xprt *xprt,
> +                                 void *data)
> +{
> +       struct rpc_xprt_switch *xps;
> +       struct rpc_xprt *main_xprt;
> +       int status = 0;
> +
> +       xprt_get(xprt);
> +
> +       rcu_read_lock();
> +       main_xprt = xprt_get(rcu_dereference(clnt->cl_xprt));
> +       xps = xprt_switch_get(rcu_dereference(clnt-
> >cl_xpi.xpi_xpswitch));
> +       status = rpc_cmp_addr_port((struct sockaddr *)&xprt->addr,
> +                               (struct sockaddr *)&main_xprt->addr);
> +       rcu_read_unlock();
> +       xprt_put(main_xprt);
> +       if (status || !test_bit(XPRT_OFFLINE, &xprt->state))
> +               goto out;
> +
> +       status = rpc_clnt_add_xprt_helper(clnt, xprt, data);
> +out:
> +       xprt_put(xprt);
> +       xprt_switch_put(xps);
> +       return status;
> +}
> +
> +void rpc_probe_trunked_xprts(struct rpc_clnt *clnt, void *data)

'data' is not a 'void *'. You patch 447574a510fc ("SUNRPC restructure
rpc_clnt_setup_test_and_add_xprt") means that only a 'struct
rpc_add_xprt_test' argument is allowed here.

> +{
> +       rpc_clnt_iterate_for_each_xprt(clnt,
> rpc_clnt_xprt_iter_offline_init,
> +                       rpc_xprt_probe_trunked, data, true);
> +}
> +EXPORT_SYMBOL_GPL(rpc_probe_trunked_xprts);
> +
>  static int rpc_xprt_offline_destroy(struct rpc_clnt *clnt,
>                                     struct rpc_xprt *xprt,
>                                     void *data)
> @@ -3071,7 +3108,7 @@ static int rpc_xprt_offline_destroy(struct
> rpc_clnt *clnt,
>  void rpc_clnt_manage_trunked_xprts(struct rpc_clnt *clnt, void
> *data)
>  {
>         rpc_clnt_iterate_for_each_xprt(clnt, NULL,
> rpc_xprt_offline_destroy,
> -                       data);
> +                       data, false);
>  }
>  EXPORT_SYMBOL_GPL(rpc_clnt_manage_trunked_xprts);
>  
> @@ -3105,7 +3142,7 @@ rpc_set_connect_timeout(struct rpc_clnt *clnt,
>         };
>         rpc_clnt_iterate_for_each_xprt(clnt, NULL,
>                         rpc_xprt_set_connect_timeout,
> -                       &timeout);
> +                       &timeout, false);
>  }
>  EXPORT_SYMBOL_GPL(rpc_set_connect_timeout);
>  
> @@ -3228,7 +3265,7 @@ rpc_clnt_swap_activate(struct rpc_clnt *clnt)
>                 clnt = clnt->cl_parent;
>         if (atomic_inc_return(&clnt->cl_swapper) == 1)
>                 return rpc_clnt_iterate_for_each_xprt(clnt, NULL,
> -                               rpc_clnt_swap_activate_callback,
> NULL);
> +                               rpc_clnt_swap_activate_callback,
> NULL, false);
>         return 0;
>  }
>  EXPORT_SYMBOL_GPL(rpc_clnt_swap_activate);
> @@ -3247,7 +3284,7 @@ rpc_clnt_swap_deactivate(struct rpc_clnt *clnt)
>  {
>         if (atomic_dec_if_positive(&clnt->cl_swapper) == 0)
>                 rpc_clnt_iterate_for_each_xprt(clnt, NULL,
> -                               rpc_clnt_swap_deactivate_callback,
> NULL);
> +                               rpc_clnt_swap_deactivate_callback,
> NULL, false);
>  }
>  EXPORT_SYMBOL_GPL(rpc_clnt_swap_deactivate);
>  #endif /* CONFIG_SUNRPC_SWAP */
> diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
> index ab60b4d3deb2..9c700bad1ec5 100644
> --- a/net/sunrpc/debugfs.c
> +++ b/net/sunrpc/debugfs.c
> @@ -160,7 +160,8 @@ rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
>         debugfs_create_file("tasks", S_IFREG | 0400, clnt-
> >cl_debugfs, clnt,
>                             &tasks_fops);
>  
> -       rpc_clnt_iterate_for_each_xprt(clnt, NULL, do_xprt_debugfs,
> &xprtnum);
> +       rpc_clnt_iterate_for_each_xprt(clnt, NULL, do_xprt_debugfs,
> &xprtnum,
> +                       false);
>  }
>  
>  void
> diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
> index e50f73a4aca5..60e2d738a8f1 100644
> --- a/net/sunrpc/stats.c
> +++ b/net/sunrpc/stats.c
> @@ -258,7 +258,7 @@ void rpc_clnt_show_stats(struct seq_file *seq,
> struct rpc_clnt *clnt)
>         seq_printf(seq, "p/v: %u/%u (%s)\n",
>                         clnt->cl_prog, clnt->cl_vers, clnt-
> >cl_program->name);
>  
> -       rpc_clnt_iterate_for_each_xprt(clnt, NULL, do_print_stats,
> seq);
> +       rpc_clnt_iterate_for_each_xprt(clnt, NULL, do_print_stats,
> seq, false);
>  
>         seq_printf(seq, "\tper-op statistics\n");
>         for (op = 0; op < maxproc; op++) {
diff mbox series

Patch

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 152da2bc5100..00778f351283 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -8533,7 +8533,7 @@  int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, const struct cred *cr
 		.cred = cred,
 	};
 	return rpc_clnt_iterate_for_each_xprt(clp->cl_rpcclient, NULL,
-			nfs4_proc_bind_conn_to_session_callback, &data);
+			nfs4_proc_bind_conn_to_session_callback, &data, false);
 }
 
 /*
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index ac1024da86c5..a0160b83d4a4 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -215,7 +215,7 @@  int		rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t);
 int 		rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt,
 			int (*setup)(struct rpc_clnt *, struct rpc_xprt_iter *),
 			int (*fn)(struct rpc_clnt *, struct rpc_xprt *, void *),
-			void *data);
+			void *data, bool do_rewind);
 
 int 		rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt,
 			struct rpc_xprt_switch *xps,
@@ -236,6 +236,7 @@  int		rpc_clnt_setup_test_and_add_xprt(struct rpc_clnt *,
 			struct rpc_xprt *,
 			void *);
 void		rpc_clnt_manage_trunked_xprts(struct rpc_clnt *, void *);
+void		rpc_probe_trunked_xprts(struct rpc_clnt *, void *);
 
 const char *rpc_proc_name(const struct rpc_task *task);
 
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 6b04b29bf842..348d0772c91d 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -830,7 +830,7 @@  int rpc_clnt_xprt_iter_offline_init(struct rpc_clnt *clnt,
 int rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt,
 		int (*setup)(struct rpc_clnt *, struct rpc_xprt_iter *),
 		int (*fn)(struct rpc_clnt *, struct rpc_xprt *, void *),
-		void *data)
+		void *data, bool do_rewind)
 {
 	struct rpc_xprt_iter xpi;
 	int ret;
@@ -850,6 +850,9 @@  int rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt,
 		xprt_put(xprt);
 		if (ret < 0)
 			break;
+
+		if (do_rewind)
+			xprt_iter_rewind(&xpi);
 	}
 	xprt_iter_destroy(&xpi);
 	return ret;
@@ -3032,6 +3035,40 @@  int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
 }
 EXPORT_SYMBOL_GPL(rpc_clnt_add_xprt);
 
+static int rpc_xprt_probe_trunked(struct rpc_clnt *clnt,
+				  struct rpc_xprt *xprt,
+				  void *data)
+{
+	struct rpc_xprt_switch *xps;
+	struct rpc_xprt *main_xprt;
+	int status = 0;
+
+	xprt_get(xprt);
+
+	rcu_read_lock();
+	main_xprt = xprt_get(rcu_dereference(clnt->cl_xprt));
+	xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch));
+	status = rpc_cmp_addr_port((struct sockaddr *)&xprt->addr,
+				(struct sockaddr *)&main_xprt->addr);
+	rcu_read_unlock();
+	xprt_put(main_xprt);
+	if (status || !test_bit(XPRT_OFFLINE, &xprt->state))
+		goto out;
+
+	status = rpc_clnt_add_xprt_helper(clnt, xprt, data);
+out:
+	xprt_put(xprt);
+	xprt_switch_put(xps);
+	return status;
+}
+
+void rpc_probe_trunked_xprts(struct rpc_clnt *clnt, void *data)
+{
+	rpc_clnt_iterate_for_each_xprt(clnt, rpc_clnt_xprt_iter_offline_init,
+			rpc_xprt_probe_trunked, data, true);
+}
+EXPORT_SYMBOL_GPL(rpc_probe_trunked_xprts);
+
 static int rpc_xprt_offline_destroy(struct rpc_clnt *clnt,
 				    struct rpc_xprt *xprt,
 				    void *data)
@@ -3071,7 +3108,7 @@  static int rpc_xprt_offline_destroy(struct rpc_clnt *clnt,
 void rpc_clnt_manage_trunked_xprts(struct rpc_clnt *clnt, void *data)
 {
 	rpc_clnt_iterate_for_each_xprt(clnt, NULL, rpc_xprt_offline_destroy,
-			data);
+			data, false);
 }
 EXPORT_SYMBOL_GPL(rpc_clnt_manage_trunked_xprts);
 
@@ -3105,7 +3142,7 @@  rpc_set_connect_timeout(struct rpc_clnt *clnt,
 	};
 	rpc_clnt_iterate_for_each_xprt(clnt, NULL,
 			rpc_xprt_set_connect_timeout,
-			&timeout);
+			&timeout, false);
 }
 EXPORT_SYMBOL_GPL(rpc_set_connect_timeout);
 
@@ -3228,7 +3265,7 @@  rpc_clnt_swap_activate(struct rpc_clnt *clnt)
 		clnt = clnt->cl_parent;
 	if (atomic_inc_return(&clnt->cl_swapper) == 1)
 		return rpc_clnt_iterate_for_each_xprt(clnt, NULL,
-				rpc_clnt_swap_activate_callback, NULL);
+				rpc_clnt_swap_activate_callback, NULL, false);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(rpc_clnt_swap_activate);
@@ -3247,7 +3284,7 @@  rpc_clnt_swap_deactivate(struct rpc_clnt *clnt)
 {
 	if (atomic_dec_if_positive(&clnt->cl_swapper) == 0)
 		rpc_clnt_iterate_for_each_xprt(clnt, NULL,
-				rpc_clnt_swap_deactivate_callback, NULL);
+				rpc_clnt_swap_deactivate_callback, NULL, false);
 }
 EXPORT_SYMBOL_GPL(rpc_clnt_swap_deactivate);
 #endif /* CONFIG_SUNRPC_SWAP */
diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c
index ab60b4d3deb2..9c700bad1ec5 100644
--- a/net/sunrpc/debugfs.c
+++ b/net/sunrpc/debugfs.c
@@ -160,7 +160,8 @@  rpc_clnt_debugfs_register(struct rpc_clnt *clnt)
 	debugfs_create_file("tasks", S_IFREG | 0400, clnt->cl_debugfs, clnt,
 			    &tasks_fops);
 
-	rpc_clnt_iterate_for_each_xprt(clnt, NULL, do_xprt_debugfs, &xprtnum);
+	rpc_clnt_iterate_for_each_xprt(clnt, NULL, do_xprt_debugfs, &xprtnum,
+			false);
 }
 
 void
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index e50f73a4aca5..60e2d738a8f1 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -258,7 +258,7 @@  void rpc_clnt_show_stats(struct seq_file *seq, struct rpc_clnt *clnt)
 	seq_printf(seq, "p/v: %u/%u (%s)\n",
 			clnt->cl_prog, clnt->cl_vers, clnt->cl_program->name);
 
-	rpc_clnt_iterate_for_each_xprt(clnt, NULL, do_print_stats, seq);
+	rpc_clnt_iterate_for_each_xprt(clnt, NULL, do_print_stats, seq, false);
 
 	seq_printf(seq, "\tper-op statistics\n");
 	for (op = 0; op < maxproc; op++) {