Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
[linux-2.6-block.git] / net / ipv4 / inet_hashtables.c
index 47ad7aab51e37f4ee5cc58a312498d4de5f4ffc4..21e5e32d8c600c192f53d8acec5f7bfeea5cfed5 100644 (file)
@@ -286,6 +286,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
        struct sock *sk2;
        const struct hlist_nulls_node *node;
        struct inet_timewait_sock *tw;
+       int twrefcnt = 0;
 
        spin_lock(lock);
 
@@ -318,20 +319,23 @@ unique:
        sk->sk_hash = hash;
        WARN_ON(!sk_unhashed(sk));
        __sk_nulls_add_node_rcu(sk, &head->chain);
+       if (tw) {
+               twrefcnt = inet_twsk_unhash(tw);
+               NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED);
+       }
        spin_unlock(lock);
+       if (twrefcnt)
+               inet_twsk_put(tw);
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
 
        if (twp) {
                *twp = tw;
-               NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED);
        } else if (tw) {
                /* Silly. Should hash-dance instead... */
                inet_twsk_deschedule(tw, death_row);
-               NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED);
 
                inet_twsk_put(tw);
        }
-
        return 0;
 
 not_unique:
@@ -454,7 +458,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
                         * unique enough.
                         */
                        inet_bind_bucket_for_each(tb, node, &head->chain) {
-                               if (ib_net(tb) == net && tb->port == port) {
+                               if (net_eq(ib_net(tb), net) &&
+                                   tb->port == port) {
                                        if (tb->fastreuse >= 0)
                                                goto next_port;
                                        WARN_ON(hlist_empty(&tb->owners));