diff options
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r-- | net/sunrpc/clnt.c | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index aa8965e9d307..d6409e757219 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -125,10 +125,9 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, | |||
125 | goto out_err; | 125 | goto out_err; |
126 | 126 | ||
127 | err = -ENOMEM; | 127 | err = -ENOMEM; |
128 | clnt = kmalloc(sizeof(*clnt), GFP_KERNEL); | 128 | clnt = kzalloc(sizeof(*clnt), GFP_KERNEL); |
129 | if (!clnt) | 129 | if (!clnt) |
130 | goto out_err; | 130 | goto out_err; |
131 | memset(clnt, 0, sizeof(*clnt)); | ||
132 | atomic_set(&clnt->cl_users, 0); | 131 | atomic_set(&clnt->cl_users, 0); |
133 | atomic_set(&clnt->cl_count, 1); | 132 | atomic_set(&clnt->cl_count, 1); |
134 | clnt->cl_parent = clnt; | 133 | clnt->cl_parent = clnt; |
@@ -922,26 +921,43 @@ call_transmit(struct rpc_task *task) | |||
922 | task->tk_status = xprt_prepare_transmit(task); | 921 | task->tk_status = xprt_prepare_transmit(task); |
923 | if (task->tk_status != 0) | 922 | if (task->tk_status != 0) |
924 | return; | 923 | return; |
924 | task->tk_action = call_transmit_status; | ||
925 | /* Encode here so that rpcsec_gss can use correct sequence number. */ | 925 | /* Encode here so that rpcsec_gss can use correct sequence number. */ |
926 | if (rpc_task_need_encode(task)) { | 926 | if (rpc_task_need_encode(task)) { |
927 | task->tk_rqstp->rq_bytes_sent = 0; | 927 | BUG_ON(task->tk_rqstp->rq_bytes_sent != 0); |
928 | call_encode(task); | 928 | call_encode(task); |
929 | /* Did the encode result in an error condition? */ | 929 | /* Did the encode result in an error condition? */ |
930 | if (task->tk_status != 0) | 930 | if (task->tk_status != 0) |
931 | goto out_nosend; | 931 | return; |
932 | } | 932 | } |
933 | task->tk_action = call_transmit_status; | ||
934 | xprt_transmit(task); | 933 | xprt_transmit(task); |
935 | if (task->tk_status < 0) | 934 | if (task->tk_status < 0) |
936 | return; | 935 | return; |
937 | if (!task->tk_msg.rpc_proc->p_decode) { | 936 | /* |
938 | task->tk_action = rpc_exit_task; | 937 | * On success, ensure that we call xprt_end_transmit() before sleeping |
939 | rpc_wake_up_task(task); | 938 | * in order to allow access to the socket to other RPC requests. |
940 | } | 939 | */ |
941 | return; | 940 | call_transmit_status(task); |
942 | out_nosend: | 941 | if (task->tk_msg.rpc_proc->p_decode != NULL) |
943 | /* release socket write lock before attempting to handle error */ | 942 | return; |
944 | xprt_abort_transmit(task); | 943 | task->tk_action = rpc_exit_task; |
944 | rpc_wake_up_task(task); | ||
945 | } | ||
946 | |||
947 | /* | ||
948 | * 5a. Handle cleanup after a transmission | ||
949 | */ | ||
950 | static void | ||
951 | call_transmit_status(struct rpc_task *task) | ||
952 | { | ||
953 | task->tk_action = call_status; | ||
954 | /* | ||
955 | * Special case: if we've been waiting on the socket's write_space() | ||
956 | * callback, then don't call xprt_end_transmit(). | ||
957 | */ | ||
958 | if (task->tk_status == -EAGAIN) | ||
959 | return; | ||
960 | xprt_end_transmit(task); | ||
945 | rpc_task_force_reencode(task); | 961 | rpc_task_force_reencode(task); |
946 | } | 962 | } |
947 | 963 | ||
@@ -993,18 +1009,7 @@ call_status(struct rpc_task *task) | |||
993 | } | 1009 | } |
994 | 1010 | ||
995 | /* | 1011 | /* |
996 | * 6a. Handle transmission errors. | 1012 | * 6a. Handle RPC timeout |
997 | */ | ||
998 | static void | ||
999 | call_transmit_status(struct rpc_task *task) | ||
1000 | { | ||
1001 | if (task->tk_status != -EAGAIN) | ||
1002 | rpc_task_force_reencode(task); | ||
1003 | call_status(task); | ||
1004 | } | ||
1005 | |||
1006 | /* | ||
1007 | * 6b. Handle RPC timeout | ||
1008 | * We do not release the request slot, so we keep using the | 1013 | * We do not release the request slot, so we keep using the |
1009 | * same XID for all retransmits. | 1014 | * same XID for all retransmits. |
1010 | */ | 1015 | */ |