On Thu, 2022-07-21 at 18:07 -0400, Olga Kornievskaia wrote: > 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@xxxxxxxxxx> > --- > include/linux/sunrpc/clnt.h | 1 + > include/linux/sunrpc/xprtmultipath.h | 2 +- > net/sunrpc/clnt.c | 16 +++++++++++++++- > net/sunrpc/xprt.c | 2 +- > net/sunrpc/xprtmultipath.c | 10 +++++----- > 5 files changed, 23 insertions(+), 8 deletions(-) > > diff --git a/include/linux/sunrpc/clnt.h > b/include/linux/sunrpc/clnt.h > index 71a3a1dd7e81..7a43fd514398 100644 > --- a/include/linux/sunrpc/clnt.h > +++ b/include/linux/sunrpc/clnt.h > @@ -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); > diff --git a/include/linux/sunrpc/xprtmultipath.h > b/include/linux/sunrpc/xprtmultipath.h > index 688ca7eb1d01..9fff0768d942 100644 > --- a/include/linux/sunrpc/xprtmultipath.h > +++ b/include/linux/sunrpc/xprtmultipath.h > @@ -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); > diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c > index 036ccf01bd25..82a829798d96 100644 > --- a/net/sunrpc/clnt.c > +++ b/net/sunrpc/clnt.c > @@ -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(x > ps, 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) > { > diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c > index 8f8e3c952f24..44348c9f4b00 100644 > --- a/net/sunrpc/xprt.c > +++ b/net/sunrpc/xprt.c > @@ -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); > } > diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c > index 8def8423fc0a..39a8a2f9c982 100644 > --- a/net/sunrpc/xprtmultipath.c > +++ b/net/sunrpc/xprtmultipath.c > @@ -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) > @@ -83,10 +83,10 @@ static void xprt_switch_remove_xprt_locked(struct > rpc_xprt_switch *xps, > * 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) > { net/sunrpc/xprtmultipath.c:87: warning: Function parameter or member 'offline' not described in 'rpc_xprt_switch_remove_xprt' You need to add a description of the new parameter in the function documentation above. > 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 +155,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); -- Trond Myklebust Linux NFS client maintainer, Hammerspace trond.myklebust@xxxxxxxxxxxxxxx