Commit 50861e89 authored by Ralf Bächle's avatar Ralf Bächle

Properly handle sleep race without cli.

parent 752728c2
...@@ -1264,28 +1264,33 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le ...@@ -1264,28 +1264,33 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
return -EINPROGRESS; return -EINPROGRESS;
cli(); /* To avoid races on the sleep */ if (sk->state == TCP_SYN_SENT) {
struct task_struct *tsk = current;
/* A DM or timeout will go to closed, a UA will go to ABM */ DECLARE_WAITQUEUE(wait, tsk);
while (sk->state == TCP_SYN_SENT) {
interruptible_sleep_on(sk->sleep); add_wait_queue(sk->sleep, &wait);
if (signal_pending(current)) { for (;;) {
sti(); set_current_state(TASK_INTERRUPTIBLE);
if (sk->state != TCP_SYN_SENT)
break;
if (!signal_pending(tsk)) {
schedule();
continue;
}
return -ERESTARTSYS; return -ERESTARTSYS;
} }
current->state = TASK_RUNNING;
remove_wait_queue(sk->sleep, &wait);
} }
if (sk->state != TCP_ESTABLISHED) { if (sk->state != TCP_ESTABLISHED) {
/* Not in ABM, not in WAIT_UA -> failed */ /* Not in ABM, not in WAIT_UA -> failed */
sti();
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
return sock_error(sk); /* Always set at this point */ return sock_error(sk); /* Always set at this point */
} }
sock->state = SS_CONNECTED; sock->state = SS_CONNECTED;
sti();
return 0; return 0;
} }
......
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