OSDN Git Service

SUNRPC: Make NFS swap work with multipath
authorTrond Myklebust <trond.myklebust@primarydata.com>
Sun, 31 Jan 2016 01:05:34 +0000 (20:05 -0500)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Fri, 5 Feb 2016 23:48:56 +0000 (18:48 -0500)
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
net/sunrpc/clnt.c

index 19feb4d..4b6ceb7 100644 (file)
@@ -2554,57 +2554,39 @@ void rpc_show_tasks(struct net *net)
 #endif
 
 #if IS_ENABLED(CONFIG_SUNRPC_SWAP)
+static int
+rpc_clnt_swap_activate_callback(struct rpc_clnt *clnt,
+               struct rpc_xprt *xprt,
+               void *dummy)
+{
+       return xprt_enable_swap(xprt);
+}
+
 int
 rpc_clnt_swap_activate(struct rpc_clnt *clnt)
 {
-       int ret = 0;
-       struct rpc_xprt *xprt;
-
-       if (atomic_inc_return(&clnt->cl_swapper) == 1) {
-retry:
-               rcu_read_lock();
-               xprt = xprt_get(rcu_dereference(clnt->cl_xprt));
-               rcu_read_unlock();
-               if (!xprt) {
-                       /*
-                        * If we didn't get a reference, then we likely are
-                        * racing with a migration event. Wait for a grace
-                        * period and try again.
-                        */
-                       synchronize_rcu();
-                       goto retry;
-               }
-
-               ret = xprt_enable_swap(xprt);
-               xprt_put(xprt);
-       }
-       return ret;
+       if (atomic_inc_return(&clnt->cl_swapper) == 1)
+               return rpc_clnt_iterate_for_each_xprt(clnt,
+                               rpc_clnt_swap_activate_callback, NULL);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(rpc_clnt_swap_activate);
 
+static int
+rpc_clnt_swap_deactivate_callback(struct rpc_clnt *clnt,
+               struct rpc_xprt *xprt,
+               void *dummy)
+{
+       xprt_disable_swap(xprt);
+       return 0;
+}
+
 void
 rpc_clnt_swap_deactivate(struct rpc_clnt *clnt)
 {
-       struct rpc_xprt *xprt;
-
-       if (atomic_dec_if_positive(&clnt->cl_swapper) == 0) {
-retry:
-               rcu_read_lock();
-               xprt = xprt_get(rcu_dereference(clnt->cl_xprt));
-               rcu_read_unlock();
-               if (!xprt) {
-                       /*
-                        * If we didn't get a reference, then we likely are
-                        * racing with a migration event. Wait for a grace
-                        * period and try again.
-                        */
-                       synchronize_rcu();
-                       goto retry;
-               }
-
-               xprt_disable_swap(xprt);
-               xprt_put(xprt);
-       }
+       if (atomic_dec_if_positive(&clnt->cl_swapper) == 0)
+               rpc_clnt_iterate_for_each_xprt(clnt,
+                               rpc_clnt_swap_deactivate_callback, NULL);
 }
 EXPORT_SYMBOL_GPL(rpc_clnt_swap_deactivate);
 #endif /* CONFIG_SUNRPC_SWAP */