diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-06-26 16:57:41 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-10 23:40:36 -0400 |
commit | 1dd17ec693bf4a08b666c2ef76b68ca08ce3c93d (patch) | |
tree | 633aabf459c0beafc5ed0ebd7c0efd2e58e7c22b /net/sunrpc/clnt.c | |
parent | 5d28dc82074f1e64b22c9424b161abc1f5d6bcdb (diff) |
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 <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r-- | net/sunrpc/clnt.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 98df44e453fe..28a789419f64 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -352,10 +352,6 @@ rpc_free_client(struct kref *kref) | |||
352 | 352 | ||
353 | dprintk("RPC: destroying %s client for %s\n", | 353 | dprintk("RPC: destroying %s client for %s\n", |
354 | clnt->cl_protname, clnt->cl_server); | 354 | clnt->cl_protname, clnt->cl_server); |
355 | if (clnt->cl_auth) { | ||
356 | rpcauth_release(clnt->cl_auth); | ||
357 | clnt->cl_auth = NULL; | ||
358 | } | ||
359 | if (!IS_ERR(clnt->cl_dentry)) { | 355 | if (!IS_ERR(clnt->cl_dentry)) { |
360 | rpc_rmdir(clnt->cl_dentry); | 356 | rpc_rmdir(clnt->cl_dentry); |
361 | rpc_put_mount(); | 357 | rpc_put_mount(); |
@@ -376,6 +372,30 @@ out_free: | |||
376 | } | 372 | } |
377 | 373 | ||
378 | /* | 374 | /* |
375 | * Free an RPC client | ||
376 | */ | ||
377 | static void | ||
378 | rpc_free_auth(struct kref *kref) | ||
379 | { | ||
380 | struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref); | ||
381 | |||
382 | if (clnt->cl_auth == NULL) { | ||
383 | rpc_free_client(kref); | ||
384 | return; | ||
385 | } | ||
386 | |||
387 | /* | ||
388 | * Note: RPCSEC_GSS may need to send NULL RPC calls in order to | ||
389 | * release remaining GSS contexts. This mechanism ensures | ||
390 | * that it can do so safely. | ||
391 | */ | ||
392 | kref_init(kref); | ||
393 | rpcauth_release(clnt->cl_auth); | ||
394 | clnt->cl_auth = NULL; | ||
395 | kref_put(kref, rpc_free_client); | ||
396 | } | ||
397 | |||
398 | /* | ||
379 | * Release reference to the RPC client | 399 | * Release reference to the RPC client |
380 | */ | 400 | */ |
381 | void | 401 | void |
@@ -385,7 +405,7 @@ rpc_release_client(struct rpc_clnt *clnt) | |||
385 | 405 | ||
386 | if (list_empty(&clnt->cl_tasks)) | 406 | if (list_empty(&clnt->cl_tasks)) |
387 | wake_up(&destroy_wait); | 407 | wake_up(&destroy_wait); |
388 | kref_put(&clnt->cl_kref, rpc_free_client); | 408 | kref_put(&clnt->cl_kref, rpc_free_auth); |
389 | } | 409 | } |
390 | 410 | ||
391 | /** | 411 | /** |