AX.25, NETROM and ROSE fixes and cleanups
Subsystems (2)
cover AX.25, NETROM and ROSE fixes and cleanups
Patches 1/3 and 2/3 are fixes for 2.6.21 and -stable. 3/3 is a cleanup even though it seems to partly paper over a connection establishment issue on extremly fast networks such as loopback I'm still chasing.
Ralf
PATCH 1/3 Remove ourselves from waitqueue when receiving a signal
net/rose/af_rose.c | 2 ++ 1 file changed, 2 insertions(+)
net/rose/af_rose.c +2 -0
@@ -877,6 +877,8 @@ static int rose_accept(struct socket *solock_sock (sk);continue ; } + current->state =TASK_RUNNING ; +remove_wait_queue (sk->sk_sleep, &wait);return -ERESTARTSYS ; } current->state =TASK_RUNNING ;
Re: [PATCH 1/3] Remove ourselves from waitqueue when receiving a signal
From: [email protected]
Date: Sun, 11 Mar 2007 22:53:20 +0000
Quoted 1 line
Signed-off-by Ralf Baechle <[email protected]>
Applied.
PATCH 2/3 Socket locking is a great invention.
In reply to [email protected]Especially if you actually try to do it ;-)
net/rose/af_rose.c | 78 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 28 deletions(-)
net/rose/af_rose.c +50 -28
@@ -700,23 +700,7 @@ static int rose_connect(struct socket *sunsigned char cause, diagnostic;struct net_device *dev;ax25_uid_assoc *user; -int n; - -if (sk->sk_state ==TCP_ESTABLISHED && sock->state ==SS_CONNECTING ) { - sock->state =SS_CONNECTED ; -return 0 ;/* Connect completed during a ERESTARTSYS event */ - } - -if (sk->sk_state ==TCP_CLOSE && sock->state ==SS_CONNECTING ) { - sock->state =SS_UNCONNECTED ; -return -ECONNREFUSED ; - } - -if (sk->sk_state ==TCP_ESTABLISHED ) -return -EISCONN ;/* No reconnect on a seqpacket socket */ - - sk->sk_state =TCP_CLOSE ; - sock->state =SS_UNCONNECTED ; +int n, err =0 ;if (addr_len !=sizeof (struct sockaddr_rose ) && addr_len !=sizeof (struct full_sockaddr_rose ))return -EINVAL ;
@@ -734,24 +718,53 @@ static int rose_connect(struct socket *sif ((rose->source_ndigis + addr->srose_ndigis) >ROSE_MAX_DIGIS )return -EINVAL ; +lock_sock (sk); + +if (sk->sk_state ==TCP_ESTABLISHED && sock->state ==SS_CONNECTING ) { +/* Connect completed during a ERESTARTSYS event */ + sock->state =SS_CONNECTED ; + goto out_release; + } + +if (sk->sk_state ==TCP_CLOSE && sock->state ==SS_CONNECTING ) { + sock->state =SS_UNCONNECTED ; + err = -ECONNREFUSED ; + goto out_release; + } + +if (sk->sk_state ==TCP_ESTABLISHED ) { +/* No reconnect on a seqpacket socket */ + err = -EISCONN ; + goto out_release; + } + + sk->sk_state =TCP_CLOSE ; + sock->state =SS_UNCONNECTED ; + rose->neighbour =rose_get_neigh (&addr->srose_addr, &cause, &diagnostic);if (!rose->neighbour)return -ENETUNREACH ; rose->lci =rose_new_lci (rose->neighbour); -if (!rose->lci) -return -ENETUNREACH ; +if (!rose->lci) { + err = -ENETUNREACH ; + goto out_release; + }if (sock_flag (sk,SOCK_ZAPPED )) {/* Must bind first - autobinding in this may or may not work */ sock_reset_flag (sk,SOCK_ZAPPED ); -if ((dev =rose_dev_first ()) ==NULL ) -return -ENETUNREACH ; +if ((dev =rose_dev_first ()) ==NULL ) { + err = -ENETUNREACH ; + goto out_release; + } user =ax25_findbyuid (current->euid); -if (!user) -return -EINVAL ; +if (!user) { + err = -EINVAL ; + goto out_release; + }memcpy (&rose->source_addr, dev->dev_addr,ROSE_ADDR_LEN ); rose->source_call = user->call;
@@ -789,8 +802,10 @@ rose_try_next_neigh:rose_start_t1timer (sk);/* Now the loop */ -if (sk->sk_state !=TCP_ESTABLISHED && (flags &O_NONBLOCK )) -return -EINPROGRESS ; +if (sk->sk_state !=TCP_ESTABLISHED && (flags &O_NONBLOCK )) { + err = -EINPROGRESS ; + goto out_release; + }/* * A Connect Ack with Choke or timeout or failed routing will go to
@@ -805,8 +820,10 @@ rose_try_next_neigh:set_current_state (TASK_INTERRUPTIBLE );if (sk->sk_state !=TCP_SYN_SENT )break ; +release_sock (sk);if (!signal_pending (tsk)) {schedule (); +lock_sock (sk);continue ; } current->state =TASK_RUNNING ;
@@ -822,14 +839,19 @@ rose_try_next_neigh: rose->neighbour =rose_get_neigh (&addr->srose_addr, &cause, &diagnostic);if (rose->neighbour) goto rose_try_next_neigh; -/* No more neighbour */ + +/* No more neighbours */ sock->state =SS_UNCONNECTED ; -return sock_error (sk);/* Always set at this point */ + err =sock_error (sk);/* Always set at this point */ + goto out_release; } sock->state =SS_CONNECTED ; -return 0 ; +out_release: +release_sock (sk); + +return err; }static int rose_accept (struct socket *sock,struct socket *newsock,int flags)
David Miller
maintainerRe: [PATCH 2/3] Socket locking is a great invention.
From: [email protected]
Date: Sun, 11 Mar 2007 22:53:21 +0000
Quoted 3 lines
Especially if you actually try to do it ;-)
Signed-off-by Ralf Baechle <[email protected]>
:-) Applied, thanks Ralf.
PATCH 3/3 Convert to use modern wait queue API
In reply to [email protected]net/ax25/af_ax25.c | 77 +++++++++++++++++++--------------------- net/netrom/af_netrom.c | 93 ++++++++++++++++++++++++------------------------- net/rose/af_rose.c | 54 +++++++++++++--------------- 3 files changed, 109 insertions(+), 115 deletions(-)
net/ax25/af_ax25.c +37 -40
@@ -1127,22 +1127,22 @@ static int __must_check ax25_connect(strswitch (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 ;
@@ -1159,12 +1159,12 @@ static int __must_check ax25_connect(str/* 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;
@@ -1194,7 +1194,7 @@ static int __must_check ax25_connect(str 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);
@@ -1203,7 +1203,7 @@ static int __must_check ax25_connect(strif (ax25->ax25_dev ==NULL ) {kfree (digi); err = -EHOSTUNREACH ; - goto out; + goto out_release; } }
@@ -1213,7 +1213,7 @@ static int __must_check ax25_connect(strkfree (digi); err = -EADDRINUSE ;/* Already such a connection */ ax25_cb_put (ax25t); - goto out; + goto out_release; } ax25->dest_addr = fsa->fsa_ax25.sax25_call;
@@ -1223,7 +1223,7 @@ static int __must_check ax25_connect(strif (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.. */
@@ -1255,55 +1255,53 @@ static int __must_check ax25_connect(str/* 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 ;
@@ -1328,30 +1326,29 @@ static int ax25_accept(struct socket *so* 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;
net/netrom/af_netrom.c +46 -47
200 lines not on this page · raw message
net/rose/af_rose.c +26 -28
111 lines not on this page · raw message
David Miller
maintainerRe: [PATCH 3/3] Convert to use modern wait queue API
From: [email protected]
Date: Sun, 11 Mar 2007 22:53:22 +0000
Quoted 1 line
Signed-off-by Ralf Baechle <[email protected]>
I'll stick this into net-2.6.22 after Linus pulls in today's fixes and I rebase net-2.6.22 using that.
Thanks.
David Miller
maintainerRe: [PATCH 3/3] Convert to use modern wait queue API
In reply to [email protected]From: [email protected]
Date: Sun, 11 Mar 2007 22:53:22 +0000
Quoted 1 line
Signed-off-by Ralf Baechle <[email protected]>
I finally applied this one, thanks for waiting so long :)