On Fri, Dec 09, 2005 at 03:50:52PM -0800, David S. Miller wrote:
> Can you toss together such a patch or would you like me to do it? :-)

Sure, it looks like there were 2 places where the test on sk_err was 
missing from the event wait logic (in sk_stream_wait_connect and 
sk_stream_wait_memory), while the rest of the sock_error() users look 
to be doing the right thing.  This version of the patch fixes those, 
and cleans up a few places that were testing ->sk_err directly.

                -ben

Signed-off-by: Benjamin LaHaise <[EMAIL PROTECTED]>
diff --git a/include/net/sock.h b/include/net/sock.h
index 982b4ec..0fbae85 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1166,7 +1166,10 @@ static inline int sock_queue_err_skb(str
  
 static inline int sock_error(struct sock *sk)
 {
-       int err = xchg(&sk->sk_err, 0);
+       int err;
+       if (likely(!sk->sk_err))
+               return 0;
+       err = xchg(&sk->sk_err, 0);
-       return -err;
+       return unlikely(-err);
 }
 
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index ea616e3..fb031fe 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -287,10 +287,9 @@ int bt_sock_wait_state(struct sock *sk, 
                timeo = schedule_timeout(timeo);
                lock_sock(sk);
 
-               if (sk->sk_err) {
-                       err = sock_error(sk);
+               err = sock_error(sk);
+               if (err)
                        break;
-               }
        }
        set_current_state(TASK_RUNNING);
        remove_wait_queue(sk->sk_sleep, &wait);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index e3bb11c..95f33cc 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -767,8 +767,9 @@ static int l2cap_sock_sendmsg(struct kio
 
        BT_DBG("sock %p, sk %p", sock, sk);
 
-       if (sk->sk_err)
-               return sock_error(sk);
+       err = sock_error(sk);
+       if (err)
+               return err;
 
        if (msg->msg_flags & MSG_OOB)
                return -EOPNOTSUPP;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 9cb00dc..6481814 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -637,8 +637,9 @@ static int sco_sock_sendmsg(struct kiocb
 
        BT_DBG("sock %p, sk %p", sock, sk);
 
-       if (sk->sk_err)
-               return sock_error(sk);
+       err = sock_error(sk);
+       if (err)
+               return err;
 
        if (msg->msg_flags & MSG_OOB)
                return -EOPNOTSUPP;
diff --git a/net/core/sock.c b/net/core/sock.c
diff --git a/net/core/stream.c b/net/core/stream.c
index 15bfd03..ed7ef8b 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -55,8 +55,9 @@ int sk_stream_wait_connect(struct sock *
        int done;
 
        do {
-               if (sk->sk_err)
-                       return sock_error(sk);
+               int err = sock_error(sk);
+               if (err)
+                       return err;
                if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
                        return -EPIPE;
                if (!*timeo_p)
@@ -67,6 +68,7 @@ int sk_stream_wait_connect(struct sock *
                prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
                sk->sk_write_pending++;
                done = sk_wait_event(sk, timeo_p,
+                                    !sk->sk_err &&
                                     !((1 << sk->sk_state) & 
                                       ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)));
                finish_wait(sk->sk_sleep, &wait);
@@ -137,7 +139,9 @@ int sk_stream_wait_memory(struct sock *s
 
                set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
                sk->sk_write_pending++;
-               sk_wait_event(sk, &current_timeo, sk_stream_memory_free(sk) &&
+               sk_wait_event(sk, &current_timeo, !sk->sk_err && 
+                                                 !(sk->sk_shutdown & 
SEND_SHUTDOWN) &&
+                                                 sk_stream_memory_free(sk) &&
                                                  vm_wait);
                sk->sk_write_pending--;
 
diff --git a/net/dccp/output.c b/net/dccp/output.c
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 6f92f9c..f121f7d 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1438,8 +1438,9 @@ static int irda_recvmsg_stream(struct ki
                        /*
                         *      POSIX 1003.1g mandates this order.
                         */
-                       if (sk->sk_err)
-                               ret = sock_error(sk);
+                       ret = sock_error(sk);
+                       if (ret)
+                               break;
                        else if (sk->sk_shutdown & RCV_SHUTDOWN)
                                ;
                        else if (noblock)
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index c3f0b07..aea02f4 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -566,10 +566,9 @@ static int llc_wait_data(struct sock *sk
                /*
                 * POSIX 1003.1g mandates this order.
                 */
-               if (sk->sk_err) {
-                       rc = sock_error(sk);
+               rc = sock_error(sk);
+               if (rc)
                        break;
-               }
                rc = 0;
                if (sk->sk_shutdown & RCV_SHUTDOWN)
                        break;
-- 
"You know, I've seen some crystals do some pretty trippy shit, man."
Don't Email: <[EMAIL PROTECTED]>.
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to