diff options
Diffstat (limited to 'net/sunrpc')
| -rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 19 | ||||
| -rw-r--r-- | net/sunrpc/backchannel_rqst.c | 6 | ||||
| -rw-r--r-- | net/sunrpc/xprtsock.c | 6 |
3 files changed, 25 insertions, 6 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 6c0513a7f992..36e431ee1c90 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -108,6 +108,7 @@ struct gss_auth { | |||
| 108 | static DEFINE_SPINLOCK(pipe_version_lock); | 108 | static DEFINE_SPINLOCK(pipe_version_lock); |
| 109 | static struct rpc_wait_queue pipe_version_rpc_waitqueue; | 109 | static struct rpc_wait_queue pipe_version_rpc_waitqueue; |
| 110 | static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); | 110 | static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); |
| 111 | static void gss_put_auth(struct gss_auth *gss_auth); | ||
| 111 | 112 | ||
| 112 | static void gss_free_ctx(struct gss_cl_ctx *); | 113 | static void gss_free_ctx(struct gss_cl_ctx *); |
| 113 | static const struct rpc_pipe_ops gss_upcall_ops_v0; | 114 | static const struct rpc_pipe_ops gss_upcall_ops_v0; |
| @@ -320,6 +321,7 @@ gss_release_msg(struct gss_upcall_msg *gss_msg) | |||
| 320 | if (gss_msg->ctx != NULL) | 321 | if (gss_msg->ctx != NULL) |
| 321 | gss_put_ctx(gss_msg->ctx); | 322 | gss_put_ctx(gss_msg->ctx); |
| 322 | rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue); | 323 | rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue); |
| 324 | gss_put_auth(gss_msg->auth); | ||
| 323 | kfree(gss_msg); | 325 | kfree(gss_msg); |
| 324 | } | 326 | } |
| 325 | 327 | ||
| @@ -498,9 +500,12 @@ gss_alloc_msg(struct gss_auth *gss_auth, | |||
| 498 | default: | 500 | default: |
| 499 | err = gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name); | 501 | err = gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name); |
| 500 | if (err) | 502 | if (err) |
| 501 | goto err_free_msg; | 503 | goto err_put_pipe_version; |
| 502 | }; | 504 | }; |
| 505 | kref_get(&gss_auth->kref); | ||
| 503 | return gss_msg; | 506 | return gss_msg; |
| 507 | err_put_pipe_version: | ||
| 508 | put_pipe_version(gss_auth->net); | ||
| 504 | err_free_msg: | 509 | err_free_msg: |
| 505 | kfree(gss_msg); | 510 | kfree(gss_msg); |
| 506 | err: | 511 | err: |
| @@ -991,6 +996,8 @@ gss_create_new(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) | |||
| 991 | gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor); | 996 | gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor); |
| 992 | if (gss_auth->service == 0) | 997 | if (gss_auth->service == 0) |
| 993 | goto err_put_mech; | 998 | goto err_put_mech; |
| 999 | if (!gssd_running(gss_auth->net)) | ||
| 1000 | goto err_put_mech; | ||
| 994 | auth = &gss_auth->rpc_auth; | 1001 | auth = &gss_auth->rpc_auth; |
| 995 | auth->au_cslack = GSS_CRED_SLACK >> 2; | 1002 | auth->au_cslack = GSS_CRED_SLACK >> 2; |
| 996 | auth->au_rslack = GSS_VERF_SLACK >> 2; | 1003 | auth->au_rslack = GSS_VERF_SLACK >> 2; |
| @@ -1062,6 +1069,12 @@ gss_free_callback(struct kref *kref) | |||
| 1062 | } | 1069 | } |
| 1063 | 1070 | ||
| 1064 | static void | 1071 | static void |
| 1072 | gss_put_auth(struct gss_auth *gss_auth) | ||
| 1073 | { | ||
| 1074 | kref_put(&gss_auth->kref, gss_free_callback); | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | static void | ||
| 1065 | gss_destroy(struct rpc_auth *auth) | 1078 | gss_destroy(struct rpc_auth *auth) |
| 1066 | { | 1079 | { |
| 1067 | struct gss_auth *gss_auth = container_of(auth, | 1080 | struct gss_auth *gss_auth = container_of(auth, |
| @@ -1082,7 +1095,7 @@ gss_destroy(struct rpc_auth *auth) | |||
| 1082 | gss_auth->gss_pipe[1] = NULL; | 1095 | gss_auth->gss_pipe[1] = NULL; |
| 1083 | rpcauth_destroy_credcache(auth); | 1096 | rpcauth_destroy_credcache(auth); |
| 1084 | 1097 | ||
| 1085 | kref_put(&gss_auth->kref, gss_free_callback); | 1098 | gss_put_auth(gss_auth); |
| 1086 | } | 1099 | } |
| 1087 | 1100 | ||
| 1088 | /* | 1101 | /* |
| @@ -1253,7 +1266,7 @@ gss_destroy_nullcred(struct rpc_cred *cred) | |||
| 1253 | call_rcu(&cred->cr_rcu, gss_free_cred_callback); | 1266 | call_rcu(&cred->cr_rcu, gss_free_cred_callback); |
| 1254 | if (ctx) | 1267 | if (ctx) |
| 1255 | gss_put_ctx(ctx); | 1268 | gss_put_ctx(ctx); |
| 1256 | kref_put(&gss_auth->kref, gss_free_callback); | 1269 | gss_put_auth(gss_auth); |
| 1257 | } | 1270 | } |
| 1258 | 1271 | ||
| 1259 | static void | 1272 | static void |
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 890a29912d5a..e860d4f7ed2a 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c | |||
| @@ -64,7 +64,6 @@ static void xprt_free_allocation(struct rpc_rqst *req) | |||
| 64 | free_page((unsigned long)xbufp->head[0].iov_base); | 64 | free_page((unsigned long)xbufp->head[0].iov_base); |
| 65 | xbufp = &req->rq_snd_buf; | 65 | xbufp = &req->rq_snd_buf; |
| 66 | free_page((unsigned long)xbufp->head[0].iov_base); | 66 | free_page((unsigned long)xbufp->head[0].iov_base); |
| 67 | list_del(&req->rq_bc_pa_list); | ||
| 68 | kfree(req); | 67 | kfree(req); |
| 69 | } | 68 | } |
| 70 | 69 | ||
| @@ -168,8 +167,10 @@ out_free: | |||
| 168 | /* | 167 | /* |
| 169 | * Memory allocation failed, free the temporary list | 168 | * Memory allocation failed, free the temporary list |
| 170 | */ | 169 | */ |
| 171 | list_for_each_entry_safe(req, tmp, &tmp_list, rq_bc_pa_list) | 170 | list_for_each_entry_safe(req, tmp, &tmp_list, rq_bc_pa_list) { |
| 171 | list_del(&req->rq_bc_pa_list); | ||
| 172 | xprt_free_allocation(req); | 172 | xprt_free_allocation(req); |
| 173 | } | ||
| 173 | 174 | ||
| 174 | dprintk("RPC: setup backchannel transport failed\n"); | 175 | dprintk("RPC: setup backchannel transport failed\n"); |
| 175 | return -ENOMEM; | 176 | return -ENOMEM; |
| @@ -198,6 +199,7 @@ void xprt_destroy_backchannel(struct rpc_xprt *xprt, unsigned int max_reqs) | |||
| 198 | xprt_dec_alloc_count(xprt, max_reqs); | 199 | xprt_dec_alloc_count(xprt, max_reqs); |
| 199 | list_for_each_entry_safe(req, tmp, &xprt->bc_pa_list, rq_bc_pa_list) { | 200 | list_for_each_entry_safe(req, tmp, &xprt->bc_pa_list, rq_bc_pa_list) { |
| 200 | dprintk("RPC: req=%p\n", req); | 201 | dprintk("RPC: req=%p\n", req); |
| 202 | list_del(&req->rq_bc_pa_list); | ||
| 201 | xprt_free_allocation(req); | 203 | xprt_free_allocation(req); |
| 202 | if (--max_reqs == 0) | 204 | if (--max_reqs == 0) |
| 203 | break; | 205 | break; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 817a1e523969..0addefca8e77 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -510,6 +510,7 @@ static int xs_nospace(struct rpc_task *task) | |||
| 510 | struct rpc_rqst *req = task->tk_rqstp; | 510 | struct rpc_rqst *req = task->tk_rqstp; |
| 511 | struct rpc_xprt *xprt = req->rq_xprt; | 511 | struct rpc_xprt *xprt = req->rq_xprt; |
| 512 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 512 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
| 513 | struct sock *sk = transport->inet; | ||
| 513 | int ret = -EAGAIN; | 514 | int ret = -EAGAIN; |
| 514 | 515 | ||
| 515 | dprintk("RPC: %5u xmit incomplete (%u left of %u)\n", | 516 | dprintk("RPC: %5u xmit incomplete (%u left of %u)\n", |
| @@ -527,7 +528,7 @@ static int xs_nospace(struct rpc_task *task) | |||
| 527 | * window size | 528 | * window size |
| 528 | */ | 529 | */ |
| 529 | set_bit(SOCK_NOSPACE, &transport->sock->flags); | 530 | set_bit(SOCK_NOSPACE, &transport->sock->flags); |
| 530 | transport->inet->sk_write_pending++; | 531 | sk->sk_write_pending++; |
| 531 | /* ...and wait for more buffer space */ | 532 | /* ...and wait for more buffer space */ |
| 532 | xprt_wait_for_buffer_space(task, xs_nospace_callback); | 533 | xprt_wait_for_buffer_space(task, xs_nospace_callback); |
| 533 | } | 534 | } |
| @@ -537,6 +538,9 @@ static int xs_nospace(struct rpc_task *task) | |||
| 537 | } | 538 | } |
| 538 | 539 | ||
| 539 | spin_unlock_bh(&xprt->transport_lock); | 540 | spin_unlock_bh(&xprt->transport_lock); |
| 541 | |||
| 542 | /* Race breaker in case memory is freed before above code is called */ | ||
| 543 | sk->sk_write_space(sk); | ||
| 540 | return ret; | 544 | return ret; |
| 541 | } | 545 | } |
| 542 | 546 | ||
