]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/sctp/input.c
Merge branch 'hibern_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik...
[linux-2.6-omap-h63xx.git] / net / sctp / input.c
index a49fa80b57b96ff2047d53d13c3a8ad134ecffbe..2e4a8646dbc389dcb55fcce1cf6b3ad0f608af0d 100644 (file)
@@ -249,6 +249,19 @@ int sctp_rcv(struct sk_buff *skb)
         */
        sctp_bh_lock_sock(sk);
 
+       if (sk != rcvr->sk) {
+               /* Our cached sk is different from the rcvr->sk.  This is
+                * because migrate()/accept() may have moved the association
+                * to a new socket and released all the sockets.  So now we
+                * are holding a lock on the old socket while the user may
+                * be doing something with the new socket.  Switch our veiw
+                * of the current sk.
+                */
+               sctp_bh_unlock_sock(sk);
+               sk = rcvr->sk;
+               sctp_bh_lock_sock(sk);
+       }
+
        if (sock_owned_by_user(sk)) {
                SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG);
                sctp_add_backlog(sk, skb);
@@ -369,7 +382,7 @@ static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
 void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
                           struct sctp_transport *t, __u32 pmtu)
 {
-       if (!t || (t->pathmtu == pmtu))
+       if (!t || (t->pathmtu <= pmtu))
                return;
 
        if (sock_owned_by_user(sk)) {