diff options
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/pmap_clnt.c | 14 | ||||
-rw-r--r-- | net/sunrpc/svc.c | 5 | ||||
-rw-r--r-- | net/sunrpc/svcauth.c | 5 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 33 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 2 |
5 files changed, 31 insertions, 28 deletions
diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c index 919d5ba7ca0a..e52afab413de 100644 --- a/net/sunrpc/pmap_clnt.c +++ b/net/sunrpc/pmap_clnt.c | |||
@@ -101,11 +101,13 @@ void rpc_getport(struct rpc_task *task) | |||
101 | /* Autobind on cloned rpc clients is discouraged */ | 101 | /* Autobind on cloned rpc clients is discouraged */ |
102 | BUG_ON(clnt->cl_parent != clnt); | 102 | BUG_ON(clnt->cl_parent != clnt); |
103 | 103 | ||
104 | if (xprt_test_and_set_binding(xprt)) { | 104 | /* Put self on queue before sending rpcbind request, in case |
105 | task->tk_status = -EACCES; /* tell caller to check again */ | 105 | * pmap_getport_done completes before we return from rpc_run_task */ |
106 | rpc_sleep_on(&xprt->binding, task, NULL, NULL); | 106 | rpc_sleep_on(&xprt->binding, task, NULL, NULL); |
107 | return; | 107 | |
108 | } | 108 | status = -EACCES; /* tell caller to check again */ |
109 | if (xprt_test_and_set_binding(xprt)) | ||
110 | goto bailout_nofree; | ||
109 | 111 | ||
110 | /* Someone else may have bound if we slept */ | 112 | /* Someone else may have bound if we slept */ |
111 | status = 0; | 113 | status = 0; |
@@ -134,8 +136,6 @@ void rpc_getport(struct rpc_task *task) | |||
134 | goto bailout; | 136 | goto bailout; |
135 | rpc_release_task(child); | 137 | rpc_release_task(child); |
136 | 138 | ||
137 | rpc_sleep_on(&xprt->binding, task, NULL, NULL); | ||
138 | |||
139 | task->tk_xprt->stat.bind_count++; | 139 | task->tk_xprt->stat.bind_count++; |
140 | return; | 140 | return; |
141 | 141 | ||
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 2807fa0eab40..eb44ec929ca1 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -828,6 +828,11 @@ svc_process(struct svc_rqst *rqstp) | |||
828 | *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); | 828 | *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); |
829 | 829 | ||
830 | /* Encode reply */ | 830 | /* Encode reply */ |
831 | if (*statp == rpc_drop_reply) { | ||
832 | if (procp->pc_release) | ||
833 | procp->pc_release(rqstp, NULL, rqstp->rq_resp); | ||
834 | goto dropit; | ||
835 | } | ||
831 | if (*statp == rpc_success && (xdr = procp->pc_encode) | 836 | if (*statp == rpc_success && (xdr = procp->pc_encode) |
832 | && !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) { | 837 | && !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) { |
833 | dprintk("svc: failed to encode reply\n"); | 838 | dprintk("svc: failed to encode reply\n"); |
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c index 8f2320aded5c..ee9bb1522d5e 100644 --- a/net/sunrpc/svcauth.c +++ b/net/sunrpc/svcauth.c | |||
@@ -126,6 +126,7 @@ void auth_domain_put(struct auth_domain *dom) | |||
126 | if (atomic_dec_and_lock(&dom->ref.refcount, &auth_domain_lock)) { | 126 | if (atomic_dec_and_lock(&dom->ref.refcount, &auth_domain_lock)) { |
127 | hlist_del(&dom->hash); | 127 | hlist_del(&dom->hash); |
128 | dom->flavour->domain_release(dom); | 128 | dom->flavour->domain_release(dom); |
129 | spin_unlock(&auth_domain_lock); | ||
129 | } | 130 | } |
130 | } | 131 | } |
131 | 132 | ||
@@ -147,10 +148,8 @@ auth_domain_lookup(char *name, struct auth_domain *new) | |||
147 | return hp; | 148 | return hp; |
148 | } | 149 | } |
149 | } | 150 | } |
150 | if (new) { | 151 | if (new) |
151 | hlist_add_head(&new->hash, head); | 152 | hlist_add_head(&new->hash, head); |
152 | kref_get(&new->ref); | ||
153 | } | ||
154 | spin_unlock(&auth_domain_lock); | 153 | spin_unlock(&auth_domain_lock); |
155 | return new; | 154 | return new; |
156 | } | 155 | } |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 61e307cca13d..64ca1f61dd94 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -299,9 +299,15 @@ void svc_reserve(struct svc_rqst *rqstp, int space) | |||
299 | static inline void | 299 | static inline void |
300 | svc_sock_put(struct svc_sock *svsk) | 300 | svc_sock_put(struct svc_sock *svsk) |
301 | { | 301 | { |
302 | if (atomic_dec_and_test(&svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) { | 302 | if (atomic_dec_and_test(&svsk->sk_inuse) && |
303 | test_bit(SK_DEAD, &svsk->sk_flags)) { | ||
303 | dprintk("svc: releasing dead socket\n"); | 304 | dprintk("svc: releasing dead socket\n"); |
304 | sock_release(svsk->sk_sock); | 305 | if (svsk->sk_sock->file) |
306 | sockfd_put(svsk->sk_sock); | ||
307 | else | ||
308 | sock_release(svsk->sk_sock); | ||
309 | if (svsk->sk_info_authunix != NULL) | ||
310 | svcauth_unix_info_release(svsk->sk_info_authunix); | ||
305 | kfree(svsk); | 311 | kfree(svsk); |
306 | } | 312 | } |
307 | } | 313 | } |
@@ -973,7 +979,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
973 | return 0; | 979 | return 0; |
974 | } | 980 | } |
975 | 981 | ||
976 | if (test_bit(SK_CONN, &svsk->sk_flags)) { | 982 | if (svsk->sk_sk->sk_state == TCP_LISTEN) { |
977 | svc_tcp_accept(svsk); | 983 | svc_tcp_accept(svsk); |
978 | svc_sock_received(svsk); | 984 | svc_sock_received(svsk); |
979 | return 0; | 985 | return 0; |
@@ -1604,20 +1610,13 @@ svc_delete_socket(struct svc_sock *svsk) | |||
1604 | if (test_bit(SK_TEMP, &svsk->sk_flags)) | 1610 | if (test_bit(SK_TEMP, &svsk->sk_flags)) |
1605 | serv->sv_tmpcnt--; | 1611 | serv->sv_tmpcnt--; |
1606 | 1612 | ||
1607 | if (!atomic_read(&svsk->sk_inuse)) { | 1613 | /* This atomic_inc should be needed - svc_delete_socket |
1608 | spin_unlock_bh(&serv->sv_lock); | 1614 | * should have the semantic of dropping a reference. |
1609 | if (svsk->sk_sock->file) | 1615 | * But it doesn't yet.... |
1610 | sockfd_put(svsk->sk_sock); | 1616 | */ |
1611 | else | 1617 | atomic_inc(&svsk->sk_inuse); |
1612 | sock_release(svsk->sk_sock); | 1618 | spin_unlock_bh(&serv->sv_lock); |
1613 | if (svsk->sk_info_authunix != NULL) | 1619 | svc_sock_put(svsk); |
1614 | svcauth_unix_info_release(svsk->sk_info_authunix); | ||
1615 | kfree(svsk); | ||
1616 | } else { | ||
1617 | spin_unlock_bh(&serv->sv_lock); | ||
1618 | dprintk(KERN_NOTICE "svc: server socket destroy delayed\n"); | ||
1619 | /* svsk->sk_server = NULL; */ | ||
1620 | } | ||
1621 | } | 1620 | } |
1622 | 1621 | ||
1623 | /* | 1622 | /* |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 28100e019225..757fc91ef25d 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -1366,7 +1366,7 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1366 | if (xprt->slot == NULL) | 1366 | if (xprt->slot == NULL) |
1367 | return -ENOMEM; | 1367 | return -ENOMEM; |
1368 | 1368 | ||
1369 | if (ntohs(addr->sin_port != 0)) | 1369 | if (ntohs(addr->sin_port) != 0) |
1370 | xprt_set_bound(xprt); | 1370 | xprt_set_bound(xprt); |
1371 | xprt->port = xs_get_random_port(); | 1371 | xprt->port = xs_get_random_port(); |
1372 | 1372 | ||