Commit ebaabbc2 authored by Chas Williams's avatar Chas Williams Committed by David S. Miller

[ATM]: svcs possible race with sigd.

parent 91859c08
...@@ -64,8 +64,8 @@ static void svc_disconnect(struct atm_vcc *vcc) ...@@ -64,8 +64,8 @@ static void svc_disconnect(struct atm_vcc *vcc)
DPRINTK("svc_disconnect %p\n",vcc); DPRINTK("svc_disconnect %p\n",vcc);
if (test_bit(ATM_VF_REGIS,&vcc->flags)) { if (test_bit(ATM_VF_REGIS,&vcc->flags)) {
sigd_enq(vcc,as_close,NULL,NULL,NULL);
add_wait_queue(&vcc->sleep,&wait); add_wait_queue(&vcc->sleep,&wait);
sigd_enq(vcc,as_close,NULL,NULL,NULL);
while (!test_bit(ATM_VF_RELEASED,&vcc->flags) && sigd) { while (!test_bit(ATM_VF_RELEASED,&vcc->flags) && sigd) {
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule(); schedule();
...@@ -124,8 +124,8 @@ static int svc_bind(struct socket *sock,struct sockaddr *sockaddr, ...@@ -124,8 +124,8 @@ static int svc_bind(struct socket *sock,struct sockaddr *sockaddr,
if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD; if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD;
vcc->local = *addr; vcc->local = *addr;
vcc->reply = WAITING; vcc->reply = WAITING;
sigd_enq(vcc,as_bind,NULL,NULL,&vcc->local);
add_wait_queue(&vcc->sleep,&wait); add_wait_queue(&vcc->sleep,&wait);
sigd_enq(vcc,as_bind,NULL,NULL,&vcc->local);
while (vcc->reply == WAITING && sigd) { while (vcc->reply == WAITING && sigd) {
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule(); schedule();
...@@ -169,12 +169,13 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr, ...@@ -169,12 +169,13 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
!vcc->qos.rxtp.traffic_class) return -EINVAL; !vcc->qos.rxtp.traffic_class) return -EINVAL;
vcc->remote = *addr; vcc->remote = *addr;
vcc->reply = WAITING; vcc->reply = WAITING;
add_wait_queue(&vcc->sleep,&wait);
sigd_enq(vcc,as_connect,NULL,NULL,&vcc->remote); sigd_enq(vcc,as_connect,NULL,NULL,&vcc->remote);
if (flags & O_NONBLOCK) { if (flags & O_NONBLOCK) {
remove_wait_queue(&vcc->sleep,&wait);
sock->state = SS_CONNECTING; sock->state = SS_CONNECTING;
return -EINPROGRESS; return -EINPROGRESS;
} }
add_wait_queue(&vcc->sleep,&wait);
error = 0; error = 0;
while (vcc->reply == WAITING && sigd) { while (vcc->reply == WAITING && sigd) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
...@@ -243,8 +244,8 @@ static int svc_listen(struct socket *sock,int backlog) ...@@ -243,8 +244,8 @@ static int svc_listen(struct socket *sock,int backlog)
/* let server handle listen on unbound sockets */ /* let server handle listen on unbound sockets */
if (test_bit(ATM_VF_SESSION,&vcc->flags)) return -EINVAL; if (test_bit(ATM_VF_SESSION,&vcc->flags)) return -EINVAL;
vcc->reply = WAITING; vcc->reply = WAITING;
sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
add_wait_queue(&vcc->sleep,&wait); add_wait_queue(&vcc->sleep,&wait);
sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
while (vcc->reply == WAITING && sigd) { while (vcc->reply == WAITING && sigd) {
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule(); schedule();
...@@ -313,8 +314,8 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags) ...@@ -313,8 +314,8 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
} }
/* wait should be short, so we ignore the non-blocking flag */ /* wait should be short, so we ignore the non-blocking flag */
new_vcc->reply = WAITING; new_vcc->reply = WAITING;
sigd_enq(new_vcc,as_accept,old_vcc,NULL,NULL);
add_wait_queue(&new_vcc->sleep,&wait); add_wait_queue(&new_vcc->sleep,&wait);
sigd_enq(new_vcc,as_accept,old_vcc,NULL,NULL);
while (new_vcc->reply == WAITING && sigd) { while (new_vcc->reply == WAITING && sigd) {
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
schedule(); schedule();
...@@ -347,8 +348,8 @@ int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos) ...@@ -347,8 +348,8 @@ int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
DECLARE_WAITQUEUE(wait,current); DECLARE_WAITQUEUE(wait,current);
vcc->reply = WAITING; vcc->reply = WAITING;
sigd_enq2(vcc,as_modify,NULL,NULL,&vcc->local,qos,0);
add_wait_queue(&vcc->sleep,&wait); add_wait_queue(&vcc->sleep,&wait);
sigd_enq2(vcc,as_modify,NULL,NULL,&vcc->local,qos,0);
while (vcc->reply == WAITING && !test_bit(ATM_VF_RELEASED,&vcc->flags) while (vcc->reply == WAITING && !test_bit(ATM_VF_RELEASED,&vcc->flags)
&& sigd) { && sigd) {
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment