From 1dd17ec693bf4a08b666c2ef76b68ca08ce3c93d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 26 Jun 2007 16:57:41 -0400 Subject: SUNRPC: Allow rpc_auth to run clean up before the rpc_client is destroyed RPCSEC_GSS needs to be able to send NULL RPC calls to the server in order to free up any remaining GSS contexts. Signed-off-by: Trond Myklebust --- net/sunrpc/clnt.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'net/sunrpc/clnt.c') diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 98df44e453f..28a789419f6 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -352,10 +352,6 @@ rpc_free_client(struct kref *kref) dprintk("RPC: destroying %s client for %s\n", clnt->cl_protname, clnt->cl_server); - if (clnt->cl_auth) { - rpcauth_release(clnt->cl_auth); - clnt->cl_auth = NULL; - } if (!IS_ERR(clnt->cl_dentry)) { rpc_rmdir(clnt->cl_dentry); rpc_put_mount(); @@ -375,6 +371,30 @@ out_free: kfree(clnt); } +/* + * Free an RPC client + */ +static void +rpc_free_auth(struct kref *kref) +{ + struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref); + + if (clnt->cl_auth == NULL) { + rpc_free_client(kref); + return; + } + + /* + * Note: RPCSEC_GSS may need to send NULL RPC calls in order to + * release remaining GSS contexts. This mechanism ensures + * that it can do so safely. + */ + kref_init(kref); + rpcauth_release(clnt->cl_auth); + clnt->cl_auth = NULL; + kref_put(kref, rpc_free_client); +} + /* * Release reference to the RPC client */ @@ -385,7 +405,7 @@ rpc_release_client(struct rpc_clnt *clnt) if (list_empty(&clnt->cl_tasks)) wake_up(&destroy_wait); - kref_put(&clnt->cl_kref, rpc_free_client); + kref_put(&clnt->cl_kref, rpc_free_auth); } /** -- cgit v1.2.3