switch (sk->sk_state) {
case TCP_SYN_SENT: /* still trying */
err = -EINPROGRESS;
- goto out;
+ goto out_release;
case TCP_ESTABLISHED: /* connection established */
sock->state = SS_CONNECTED;
- goto out;
+ goto out_release;
case TCP_CLOSE: /* connection refused */
sock->state = SS_UNCONNECTED;
err = -ECONNREFUSED;
- goto out;
+ goto out_release;
}
}
if (sk->sk_state == TCP_ESTABLISHED && sk->sk_type == SOCK_SEQPACKET) {
err = -EISCONN; /* No reconnect on a seqpacket socket */
- goto out;
+ goto out_release;
}
sk->sk_state = TCP_CLOSE;
/* Valid number of digipeaters ? */
if (fsa->fsa_ax25.sax25_ndigis < 1 || fsa->fsa_ax25.sax25_ndigis > AX25_MAX_DIGIS) {
err = -EINVAL;
- goto out;
+ goto out_release;
}
if ((digi = kmalloc(sizeof(ax25_digi), GFP_KERNEL)) == NULL) {
err = -ENOBUFS;
- goto out;
+ goto out_release;
}
digi->ndigi = fsa->fsa_ax25.sax25_ndigis;
current->comm);
if ((err = ax25_rt_autobind(ax25, &fsa->fsa_ax25.sax25_call)) < 0) {
kfree(digi);
- goto out;
+ goto out_release;
}
ax25_fillin_cb(ax25, ax25->ax25_dev);
if (ax25->ax25_dev == NULL) {
kfree(digi);
err = -EHOSTUNREACH;
- goto out;
+ goto out_release;
}
}
kfree(digi);
err = -EADDRINUSE; /* Already such a connection */
ax25_cb_put(ax25t);
- goto out;
+ goto out_release;
}
ax25->dest_addr = fsa->fsa_ax25.sax25_call;
if (sk->sk_type != SOCK_SEQPACKET) {
sock->state = SS_CONNECTED;
sk->sk_state = TCP_ESTABLISHED;
- goto out;
+ goto out_release;
}
/* Move to connecting socket, ax.25 lapb WAIT_UA.. */
/* Now the loop */
if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) {
err = -EINPROGRESS;
- goto out;
+ goto out_release;
}
if (sk->sk_state == TCP_SYN_SENT) {
- struct task_struct *tsk = current;
- DECLARE_WAITQUEUE(wait, tsk);
+ DEFINE_WAIT(wait);
- add_wait_queue(sk->sk_sleep, &wait);
for (;;) {
+ prepare_to_wait(sk->sk_sleep, &wait,
+ TASK_INTERRUPTIBLE);
if (sk->sk_state != TCP_SYN_SENT)
break;
- set_current_state(TASK_INTERRUPTIBLE);
- release_sock(sk);
- if (!signal_pending(tsk)) {
+ if (!signal_pending(current)) {
+ release_sock(sk);
schedule();
lock_sock(sk);
continue;
}
- current->state = TASK_RUNNING;
- remove_wait_queue(sk->sk_sleep, &wait);
- return -ERESTARTSYS;
+ err = -ERESTARTSYS;
+ break;
}
- current->state = TASK_RUNNING;
- remove_wait_queue(sk->sk_sleep, &wait);
+ finish_wait(sk->sk_sleep, &wait);
+
+ if (err)
+ goto out_release;
}
if (sk->sk_state != TCP_ESTABLISHED) {
/* Not in ABM, not in WAIT_UA -> failed */
sock->state = SS_UNCONNECTED;
err = sock_error(sk); /* Always set at this point */
- goto out;
+ goto out_release;
}
sock->state = SS_CONNECTED;
- err=0;
-out:
+ err = 0;
+out_release:
release_sock(sk);
return err;
}
-
static int ax25_accept(struct socket *sock, struct socket *newsock, int flags)
{
- struct task_struct *tsk = current;
- DECLARE_WAITQUEUE(wait, tsk);
struct sk_buff *skb;
struct sock *newsk;
+ DEFINE_WAIT(wait);
struct sock *sk;
int err = 0;
* The read queue this time is holding sockets ready to use
* hooked into the SABM we saved
*/
- add_wait_queue(sk->sk_sleep, &wait);
for (;;) {
+ prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
skb = skb_dequeue(&sk->sk_receive_queue);
if (skb)
break;
- release_sock(sk);
- current->state = TASK_INTERRUPTIBLE;
if (flags & O_NONBLOCK) {
- current->state = TASK_RUNNING;
- remove_wait_queue(sk->sk_sleep, &wait);
- return -EWOULDBLOCK;
+ err = -EWOULDBLOCK;
+ break;
}
- if (!signal_pending(tsk)) {
+ if (!signal_pending(current)) {
+ release_sock(sk);
schedule();
lock_sock(sk);
continue;
}
- current->state = TASK_RUNNING;
- remove_wait_queue(sk->sk_sleep, &wait);
- return -ERESTARTSYS;
+ err = -ERESTARTSYS;
+ break;
}
- current->state = TASK_RUNNING;
- remove_wait_queue(sk->sk_sleep, &wait);
+ finish_wait(sk->sk_sleep, &wait);
+
+ if (err)
+ goto out;
newsk = skb->sk;
newsk->sk_socket = newsock;