diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-10-08 03:14:51 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-10-08 03:15:00 -0400 |
| commit | 153db80f8cf74e8700cac96305b6c0b92918f17c (patch) | |
| tree | c2afb28e7b3f4fbf0aacd9edd39d7f895321ca0c /net/sunrpc/clnt.c | |
| parent | 5fd03ddab7fdbc44bfb2d183a4531c26a8dbca5a (diff) | |
| parent | cb655d0f3d57c23db51b981648e452988c0223f9 (diff) | |
Merge commit 'v2.6.36-rc7' into core/memblock
Merge reason: Update from -rc3 to -rc7.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'net/sunrpc/clnt.c')
| -rw-r--r-- | net/sunrpc/clnt.c | 116 |
1 files changed, 57 insertions, 59 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 2388d83b68ff..fa5549079d79 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -226,7 +226,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru | |||
| 226 | goto out_no_principal; | 226 | goto out_no_principal; |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | kref_init(&clnt->cl_kref); | 229 | atomic_set(&clnt->cl_count, 1); |
| 230 | 230 | ||
| 231 | err = rpc_setup_pipedir(clnt, program->pipe_dir_name); | 231 | err = rpc_setup_pipedir(clnt, program->pipe_dir_name); |
| 232 | if (err < 0) | 232 | if (err < 0) |
| @@ -390,14 +390,14 @@ rpc_clone_client(struct rpc_clnt *clnt) | |||
| 390 | if (new->cl_principal == NULL) | 390 | if (new->cl_principal == NULL) |
| 391 | goto out_no_principal; | 391 | goto out_no_principal; |
| 392 | } | 392 | } |
| 393 | kref_init(&new->cl_kref); | 393 | atomic_set(&new->cl_count, 1); |
| 394 | err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); | 394 | err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); |
| 395 | if (err != 0) | 395 | if (err != 0) |
| 396 | goto out_no_path; | 396 | goto out_no_path; |
| 397 | if (new->cl_auth) | 397 | if (new->cl_auth) |
| 398 | atomic_inc(&new->cl_auth->au_count); | 398 | atomic_inc(&new->cl_auth->au_count); |
| 399 | xprt_get(clnt->cl_xprt); | 399 | xprt_get(clnt->cl_xprt); |
| 400 | kref_get(&clnt->cl_kref); | 400 | atomic_inc(&clnt->cl_count); |
| 401 | rpc_register_client(new); | 401 | rpc_register_client(new); |
| 402 | rpciod_up(); | 402 | rpciod_up(); |
| 403 | return new; | 403 | return new; |
| @@ -465,10 +465,8 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client); | |||
| 465 | * Free an RPC client | 465 | * Free an RPC client |
| 466 | */ | 466 | */ |
| 467 | static void | 467 | static void |
| 468 | rpc_free_client(struct kref *kref) | 468 | rpc_free_client(struct rpc_clnt *clnt) |
| 469 | { | 469 | { |
| 470 | struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref); | ||
| 471 | |||
| 472 | dprintk("RPC: destroying %s client for %s\n", | 470 | dprintk("RPC: destroying %s client for %s\n", |
| 473 | clnt->cl_protname, clnt->cl_server); | 471 | clnt->cl_protname, clnt->cl_server); |
| 474 | if (!IS_ERR(clnt->cl_path.dentry)) { | 472 | if (!IS_ERR(clnt->cl_path.dentry)) { |
| @@ -495,12 +493,10 @@ out_free: | |||
| 495 | * Free an RPC client | 493 | * Free an RPC client |
| 496 | */ | 494 | */ |
| 497 | static void | 495 | static void |
| 498 | rpc_free_auth(struct kref *kref) | 496 | rpc_free_auth(struct rpc_clnt *clnt) |
| 499 | { | 497 | { |
| 500 | struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref); | ||
| 501 | |||
| 502 | if (clnt->cl_auth == NULL) { | 498 | if (clnt->cl_auth == NULL) { |
| 503 | rpc_free_client(kref); | 499 | rpc_free_client(clnt); |
| 504 | return; | 500 | return; |
| 505 | } | 501 | } |
| 506 | 502 | ||
| @@ -509,10 +505,11 @@ rpc_free_auth(struct kref *kref) | |||
| 509 | * release remaining GSS contexts. This mechanism ensures | 505 | * release remaining GSS contexts. This mechanism ensures |
| 510 | * that it can do so safely. | 506 | * that it can do so safely. |
| 511 | */ | 507 | */ |
| 512 | kref_init(kref); | 508 | atomic_inc(&clnt->cl_count); |
| 513 | rpcauth_release(clnt->cl_auth); | 509 | rpcauth_release(clnt->cl_auth); |
| 514 | clnt->cl_auth = NULL; | 510 | clnt->cl_auth = NULL; |
| 515 | kref_put(kref, rpc_free_client); | 511 | if (atomic_dec_and_test(&clnt->cl_count)) |
| 512 | rpc_free_client(clnt); | ||
| 516 | } | 513 | } |
| 517 | 514 | ||
| 518 | /* | 515 | /* |
| @@ -525,7 +522,8 @@ rpc_release_client(struct rpc_clnt *clnt) | |||
| 525 | 522 | ||
| 526 | if (list_empty(&clnt->cl_tasks)) | 523 | if (list_empty(&clnt->cl_tasks)) |
| 527 | wake_up(&destroy_wait); | 524 | wake_up(&destroy_wait); |
| 528 | kref_put(&clnt->cl_kref, rpc_free_auth); | 525 | if (atomic_dec_and_test(&clnt->cl_count)) |
| 526 | rpc_free_auth(clnt); | ||
| 529 | } | 527 | } |
| 530 | 528 | ||
| 531 | /** | 529 | /** |
| @@ -588,7 +586,7 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt) | |||
| 588 | if (clnt != NULL) { | 586 | if (clnt != NULL) { |
| 589 | rpc_task_release_client(task); | 587 | rpc_task_release_client(task); |
| 590 | task->tk_client = clnt; | 588 | task->tk_client = clnt; |
| 591 | kref_get(&clnt->cl_kref); | 589 | atomic_inc(&clnt->cl_count); |
| 592 | if (clnt->cl_softrtry) | 590 | if (clnt->cl_softrtry) |
| 593 | task->tk_flags |= RPC_TASK_SOFT; | 591 | task->tk_flags |= RPC_TASK_SOFT; |
| 594 | /* Add to the client's list of all tasks */ | 592 | /* Add to the client's list of all tasks */ |
| @@ -931,7 +929,7 @@ call_reserveresult(struct rpc_task *task) | |||
| 931 | task->tk_status = 0; | 929 | task->tk_status = 0; |
| 932 | if (status >= 0) { | 930 | if (status >= 0) { |
| 933 | if (task->tk_rqstp) { | 931 | if (task->tk_rqstp) { |
| 934 | task->tk_action = call_allocate; | 932 | task->tk_action = call_refresh; |
| 935 | return; | 933 | return; |
| 936 | } | 934 | } |
| 937 | 935 | ||
| @@ -966,13 +964,54 @@ call_reserveresult(struct rpc_task *task) | |||
| 966 | } | 964 | } |
| 967 | 965 | ||
| 968 | /* | 966 | /* |
| 969 | * 2. Allocate the buffer. For details, see sched.c:rpc_malloc. | 967 | * 2. Bind and/or refresh the credentials |
| 968 | */ | ||
| 969 | static void | ||
| 970 | call_refresh(struct rpc_task *task) | ||
| 971 | { | ||
| 972 | dprint_status(task); | ||
| 973 | |||
| 974 | task->tk_action = call_refreshresult; | ||
| 975 | task->tk_status = 0; | ||
| 976 | task->tk_client->cl_stats->rpcauthrefresh++; | ||
| 977 | rpcauth_refreshcred(task); | ||
| 978 | } | ||
| 979 | |||
| 980 | /* | ||
| 981 | * 2a. Process the results of a credential refresh | ||
| 982 | */ | ||
| 983 | static void | ||
| 984 | call_refreshresult(struct rpc_task *task) | ||
| 985 | { | ||
| 986 | int status = task->tk_status; | ||
| 987 | |||
| 988 | dprint_status(task); | ||
| 989 | |||
| 990 | task->tk_status = 0; | ||
| 991 | task->tk_action = call_allocate; | ||
| 992 | if (status >= 0 && rpcauth_uptodatecred(task)) | ||
| 993 | return; | ||
| 994 | switch (status) { | ||
| 995 | case -EACCES: | ||
| 996 | rpc_exit(task, -EACCES); | ||
| 997 | return; | ||
| 998 | case -ENOMEM: | ||
| 999 | rpc_exit(task, -ENOMEM); | ||
| 1000 | return; | ||
| 1001 | case -ETIMEDOUT: | ||
| 1002 | rpc_delay(task, 3*HZ); | ||
| 1003 | } | ||
| 1004 | task->tk_action = call_refresh; | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | /* | ||
| 1008 | * 2b. Allocate the buffer. For details, see sched.c:rpc_malloc. | ||
| 970 | * (Note: buffer memory is freed in xprt_release). | 1009 | * (Note: buffer memory is freed in xprt_release). |
| 971 | */ | 1010 | */ |
| 972 | static void | 1011 | static void |
| 973 | call_allocate(struct rpc_task *task) | 1012 | call_allocate(struct rpc_task *task) |
| 974 | { | 1013 | { |
| 975 | unsigned int slack = task->tk_client->cl_auth->au_cslack; | 1014 | unsigned int slack = task->tk_rqstp->rq_cred->cr_auth->au_cslack; |
| 976 | struct rpc_rqst *req = task->tk_rqstp; | 1015 | struct rpc_rqst *req = task->tk_rqstp; |
| 977 | struct rpc_xprt *xprt = task->tk_xprt; | 1016 | struct rpc_xprt *xprt = task->tk_xprt; |
| 978 | struct rpc_procinfo *proc = task->tk_msg.rpc_proc; | 1017 | struct rpc_procinfo *proc = task->tk_msg.rpc_proc; |
| @@ -980,7 +1019,7 @@ call_allocate(struct rpc_task *task) | |||
| 980 | dprint_status(task); | 1019 | dprint_status(task); |
| 981 | 1020 | ||
| 982 | task->tk_status = 0; | 1021 | task->tk_status = 0; |
| 983 | task->tk_action = call_refresh; | 1022 | task->tk_action = call_bind; |
| 984 | 1023 | ||
| 985 | if (req->rq_buffer) | 1024 | if (req->rq_buffer) |
| 986 | return; | 1025 | return; |
| @@ -1017,47 +1056,6 @@ call_allocate(struct rpc_task *task) | |||
| 1017 | rpc_exit(task, -ERESTARTSYS); | 1056 | rpc_exit(task, -ERESTARTSYS); |
| 1018 | } | 1057 | } |
| 1019 | 1058 | ||
| 1020 | /* | ||
| 1021 | * 2a. Bind and/or refresh the credentials | ||
| 1022 | */ | ||
| 1023 | static void | ||
| 1024 | call_refresh(struct rpc_task *task) | ||
| 1025 | { | ||
| 1026 | dprint_status(task); | ||
| 1027 | |||
| 1028 | task->tk_action = call_refreshresult; | ||
| 1029 | task->tk_status = 0; | ||
| 1030 | task->tk_client->cl_stats->rpcauthrefresh++; | ||
| 1031 | rpcauth_refreshcred(task); | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | /* | ||
| 1035 | * 2b. Process the results of a credential refresh | ||
| 1036 | */ | ||
| 1037 | static void | ||
| 1038 | call_refreshresult(struct rpc_task *task) | ||
| 1039 | { | ||
| 1040 | int status = task->tk_status; | ||
| 1041 | |||
| 1042 | dprint_status(task); | ||
| 1043 | |||
| 1044 | task->tk_status = 0; | ||
| 1045 | task->tk_action = call_bind; | ||
| 1046 | if (status >= 0 && rpcauth_uptodatecred(task)) | ||
| 1047 | return; | ||
| 1048 | switch (status) { | ||
| 1049 | case -EACCES: | ||
| 1050 | rpc_exit(task, -EACCES); | ||
| 1051 | return; | ||
| 1052 | case -ENOMEM: | ||
| 1053 | rpc_exit(task, -ENOMEM); | ||
| 1054 | return; | ||
| 1055 | case -ETIMEDOUT: | ||
| 1056 | rpc_delay(task, 3*HZ); | ||
| 1057 | } | ||
| 1058 | task->tk_action = call_refresh; | ||
| 1059 | } | ||
| 1060 | |||
| 1061 | static inline int | 1059 | static inline int |
| 1062 | rpc_task_need_encode(struct rpc_task *task) | 1060 | rpc_task_need_encode(struct rpc_task *task) |
| 1063 | { | 1061 | { |
