diff options
author | Dave Kleikamp <shaggy@linux.vnet.ibm.com> | 2009-02-02 13:40:55 -0600 |
---|---|---|
committer | Dave Kleikamp <shaggy@linux.vnet.ibm.com> | 2009-02-02 13:40:55 -0600 |
commit | 8db0c5d5ef3ab99fe9e5151872b75f45c4282e3c (patch) | |
tree | da9759151e00221c58cdd9f4de893c0b08753670 /net/sctp/input.c | |
parent | 1ad53a98c927a9b5b1b57288ac0edec562fbcf8d (diff) | |
parent | 45c82b5a770be66845687a7d027c8b52946d59af (diff) |
Merge branch 'master' of /home/shaggy/git/linus-clean/
Diffstat (limited to 'net/sctp/input.c')
-rw-r--r-- | net/sctp/input.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index bf612d954d41..2e4a8646dbc3 100644 --- a/net/sctp/input.c +++ b/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); |