|
@@ -750,14 +750,16 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client);
|
|
|
/*
|
|
|
* Free an RPC client
|
|
|
*/
|
|
|
-static void
|
|
|
+static struct rpc_clnt *
|
|
|
rpc_free_client(struct rpc_clnt *clnt)
|
|
|
{
|
|
|
+ struct rpc_clnt *parent = NULL;
|
|
|
+
|
|
|
dprintk_rcu("RPC: destroying %s client for %s\n",
|
|
|
clnt->cl_program->name,
|
|
|
rcu_dereference(clnt->cl_xprt)->servername);
|
|
|
if (clnt->cl_parent != clnt)
|
|
|
- rpc_release_client(clnt->cl_parent);
|
|
|
+ parent = clnt->cl_parent;
|
|
|
rpc_clnt_remove_pipedir(clnt);
|
|
|
rpc_unregister_client(clnt);
|
|
|
rpc_free_iostats(clnt->cl_metrics);
|
|
@@ -766,18 +768,17 @@ rpc_free_client(struct rpc_clnt *clnt)
|
|
|
rpciod_down();
|
|
|
rpc_free_clid(clnt);
|
|
|
kfree(clnt);
|
|
|
+ return parent;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* Free an RPC client
|
|
|
*/
|
|
|
-static void
|
|
|
+static struct rpc_clnt *
|
|
|
rpc_free_auth(struct rpc_clnt *clnt)
|
|
|
{
|
|
|
- if (clnt->cl_auth == NULL) {
|
|
|
- rpc_free_client(clnt);
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (clnt->cl_auth == NULL)
|
|
|
+ return rpc_free_client(clnt);
|
|
|
|
|
|
/*
|
|
|
* Note: RPCSEC_GSS may need to send NULL RPC calls in order to
|
|
@@ -788,7 +789,8 @@ rpc_free_auth(struct rpc_clnt *clnt)
|
|
|
rpcauth_release(clnt->cl_auth);
|
|
|
clnt->cl_auth = NULL;
|
|
|
if (atomic_dec_and_test(&clnt->cl_count))
|
|
|
- rpc_free_client(clnt);
|
|
|
+ return rpc_free_client(clnt);
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -799,10 +801,13 @@ rpc_release_client(struct rpc_clnt *clnt)
|
|
|
{
|
|
|
dprintk("RPC: rpc_release_client(%p)\n", clnt);
|
|
|
|
|
|
- if (list_empty(&clnt->cl_tasks))
|
|
|
- wake_up(&destroy_wait);
|
|
|
- if (atomic_dec_and_test(&clnt->cl_count))
|
|
|
- rpc_free_auth(clnt);
|
|
|
+ do {
|
|
|
+ if (list_empty(&clnt->cl_tasks))
|
|
|
+ wake_up(&destroy_wait);
|
|
|
+ if (!atomic_dec_and_test(&clnt->cl_count))
|
|
|
+ break;
|
|
|
+ clnt = rpc_free_auth(clnt);
|
|
|
+ } while (clnt != NULL);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(rpc_release_client);
|
|
|
|