SUNRPC create an rpc function that allows xprt removal from rpc_clnt
authorOlga Kornievskaia <olga.kornievskaia@gmail.com>
Mon, 25 Jul 2022 13:32:26 +0000 (09:32 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 25 Jul 2022 14:06:04 +0000 (10:06 -0400)
Expose a function that allows a removal of xprt from the rpc_clnt.

When called from NFS that's running a trunked transport then don't
decrement the active transport counter.

Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
include/linux/sunrpc/clnt.h
include/linux/sunrpc/xprtmultipath.h
net/sunrpc/clnt.c
net/sunrpc/xprt.c
net/sunrpc/xprtmultipath.c

index 71a3a1d..7a43fd5 100644 (file)
@@ -240,6 +240,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 *);
+void rpc_clnt_xprt_switch_remove_xprt(struct rpc_clnt *, struct rpc_xprt *);
 bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
                        const struct sockaddr *sap);
 void rpc_clnt_xprt_set_online(struct rpc_clnt *clnt, struct rpc_xprt *xprt);
index 688ca7e..9fff076 100644 (file)
@@ -55,7 +55,7 @@ extern void rpc_xprt_switch_set_roundrobin(struct rpc_xprt_switch *xps);
 extern void rpc_xprt_switch_add_xprt(struct rpc_xprt_switch *xps,
                struct rpc_xprt *xprt);
 extern void rpc_xprt_switch_remove_xprt(struct rpc_xprt_switch *xps,
-               struct rpc_xprt *xprt);
+               struct rpc_xprt *xprt, bool offline);
 
 extern void xprt_iter_init(struct rpc_xprt_iter *xpi,
                struct rpc_xprt_switch *xps);
index 9dbce3b..26f3102 100644 (file)
@@ -2144,7 +2144,8 @@ call_connect_status(struct rpc_task *task)
                                xprt_release(task);
                                value = atomic_long_dec_return(&xprt->queuelen);
                                if (value == 0)
-                                       rpc_xprt_switch_remove_xprt(xps, saved);
+                                       rpc_xprt_switch_remove_xprt(xps, saved,
+                                                                   true);
                                xprt_put(saved);
                                task->tk_xprt = NULL;
                                task->tk_action = call_start;
@@ -3118,6 +3119,19 @@ void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt)
 }
 EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_add_xprt);
 
+void rpc_clnt_xprt_switch_remove_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt)
+{
+       struct rpc_xprt_switch *xps;
+
+       rcu_read_lock();
+       xps = rcu_dereference(clnt->cl_xpi.xpi_xpswitch);
+       rpc_xprt_switch_remove_xprt(rcu_dereference(clnt->cl_xpi.xpi_xpswitch),
+                                   xprt, 0);
+       xps->xps_nunique_destaddr_xprts--;
+       rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_remove_xprt);
+
 bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
                                   const struct sockaddr *sap)
 {
index 8f8e3c9..44348c9 100644 (file)
@@ -2182,5 +2182,5 @@ void xprt_delete_locked(struct rpc_xprt *xprt, struct rpc_xprt_switch *xps)
 
        if (!xprt->sending.qlen && !xprt->pending.qlen &&
            !xprt->backlog.qlen && !atomic_long_read(&xprt->queuelen))
-               rpc_xprt_switch_remove_xprt(xps, xprt);
+               rpc_xprt_switch_remove_xprt(xps, xprt, true);
 }
index 8def842..55da017 100644 (file)
@@ -62,11 +62,11 @@ void rpc_xprt_switch_add_xprt(struct rpc_xprt_switch *xps,
 }
 
 static void xprt_switch_remove_xprt_locked(struct rpc_xprt_switch *xps,
-               struct rpc_xprt *xprt)
+               struct rpc_xprt *xprt, bool offline)
 {
        if (unlikely(xprt == NULL))
                return;
-       if (!test_bit(XPRT_OFFLINE, &xprt->state))
+       if (!test_bit(XPRT_OFFLINE, &xprt->state) && offline)
                xps->xps_nactive--;
        xps->xps_nxprts--;
        if (xps->xps_nxprts == 0)
@@ -79,14 +79,15 @@ static void xprt_switch_remove_xprt_locked(struct rpc_xprt_switch *xps,
  * rpc_xprt_switch_remove_xprt - Removes an rpc_xprt from a rpc_xprt_switch
  * @xps: pointer to struct rpc_xprt_switch
  * @xprt: pointer to struct rpc_xprt
+ * @offline: indicates if the xprt that's being removed is in an offline state
  *
  * Removes xprt from the list of struct rpc_xprt in xps.
  */
 void rpc_xprt_switch_remove_xprt(struct rpc_xprt_switch *xps,
-               struct rpc_xprt *xprt)
+               struct rpc_xprt *xprt, bool offline)
 {
        spin_lock(&xps->xps_lock);
-       xprt_switch_remove_xprt_locked(xps, xprt);
+       xprt_switch_remove_xprt_locked(xps, xprt, offline);
        spin_unlock(&xps->xps_lock);
        xprt_put(xprt);
 }
@@ -155,7 +156,7 @@ static void xprt_switch_free_entries(struct rpc_xprt_switch *xps)
 
                xprt = list_first_entry(&xps->xps_xprt_list,
                                struct rpc_xprt, xprt_switch);
-               xprt_switch_remove_xprt_locked(xps, xprt);
+               xprt_switch_remove_xprt_locked(xps, xprt, true);
                spin_unlock(&xps->xps_lock);
                xprt_put(xprt);
                spin_lock(&xps->xps_lock);