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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Olga Kornievskaia <kolga@xxxxxxxxxx>

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@xxxxxxxxxx>
---
 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);
 	}
 	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++) {
-- 
2.27.0




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux