From 8a1c34f374e6ad1eaccb6953d11ef142b9aa730e Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Thu, 22 Jan 2009 14:53:23 -0800 Subject: [PATCH] --- yaml --- r: 130190 b: refs/heads/master c: ae53b5bd77719fed58086c5be60ce4f22bffe1c6 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/net/sctp/input.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 30d33ea09eb6..c4f4bf7e65e4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 759af00ebef858015eb68876ac1f383bcb6a1774 +refs/heads/master: ae53b5bd77719fed58086c5be60ce4f22bffe1c6 diff --git a/trunk/net/sctp/input.c b/trunk/net/sctp/input.c index bf612d954d41..2e4a8646dbc3 100644 --- a/trunk/net/sctp/input.c +++ b/trunk/net/sctp/input.c @@ -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);