/* Must be called with locally disabled BHs. */
static void tcp_timewait_kill(struct tcp_tw_bucket *tw)
{
- struct tcp_ehash_bucket *ehead;
- struct tcp_bind_hashbucket *bhead;
- struct tcp_bind_bucket *tb;
-
+ struct inet_bind_hashbucket *bhead;
+ struct inet_bind_bucket *tb;
/* Unlink from established hashes. */
- ehead = &tcp_ehash[tw->tw_hashent];
+ struct inet_ehash_bucket *ehead = &tcp_hashinfo.ehash[tw->tw_hashent];
+
write_lock(&ehead->lock);
if (hlist_unhashed(&tw->tw_node)) {
write_unlock(&ehead->lock);
write_unlock(&ehead->lock);
/* Disassociate with bind bucket. */
- bhead = &tcp_bhash[tcp_bhashfn(tw->tw_num)];
+ bhead = &tcp_hashinfo.bhash[inet_bhashfn(tw->tw_num, tcp_hashinfo.bhash_size)];
spin_lock(&bhead->lock);
tb = tw->tw_tb;
__hlist_del(&tw->tw_bind_node);
tw->tw_tb = NULL;
- tcp_bucket_destroy(tb);
+ inet_bind_bucket_destroy(tcp_hashinfo.bind_bucket_cachep, tb);
spin_unlock(&bhead->lock);
-#ifdef INET_REFCNT_DEBUG
+#ifdef SOCK_REFCNT_DEBUG
if (atomic_read(&tw->tw_refcnt) != 1) {
printk(KERN_DEBUG "tw_bucket %p refcnt=%d\n", tw,
atomic_read(&tw->tw_refcnt));
*/
static void __tcp_tw_hashdance(struct sock *sk, struct tcp_tw_bucket *tw)
{
- struct tcp_ehash_bucket *ehead = &tcp_ehash[sk->sk_hashent];
- struct tcp_bind_hashbucket *bhead;
-
+ const struct inet_sock *inet = inet_sk(sk);
+ struct inet_ehash_bucket *ehead = &tcp_hashinfo.ehash[sk->sk_hashent];
+ struct inet_bind_hashbucket *bhead;
/* Step 1: Put TW into bind hash. Original socket stays there too.
- Note, that any socket with inet_sk(sk)->num != 0 MUST be bound in
+ Note, that any socket with inet->num != 0 MUST be bound in
binding cache, even if it is closed.
*/
- bhead = &tcp_bhash[tcp_bhashfn(inet_sk(sk)->num)];
+ bhead = &tcp_hashinfo.bhash[inet_bhashfn(inet->num, tcp_hashinfo.bhash_size)];
spin_lock(&bhead->lock);
- tw->tw_tb = tcp_sk(sk)->bind_hash;
- BUG_TRAP(tcp_sk(sk)->bind_hash);
+ tw->tw_tb = inet->bind_hash;
+ BUG_TRAP(inet->bind_hash);
tw_add_bind_node(tw, &tw->tw_tb->owners);
spin_unlock(&bhead->lock);
sock_prot_dec_use(sk->sk_prot);
/* Step 3: Hash TW into TIMEWAIT half of established hash table. */
- tw_add_node(tw, &(ehead + tcp_ehash_size)->chain);
+ tw_add_node(tw, &(ehead + tcp_hashinfo.ehash_size)->chain);
atomic_inc(&tw->tw_refcnt);
write_unlock(&ehead->lock);
if(newsk != NULL) {
struct inet_request_sock *ireq = inet_rsk(req);
struct tcp_request_sock *treq = tcp_rsk(req);
+ struct inet_sock *newinet = inet_sk(newsk);
struct tcp_sock *newtp;
struct sk_filter *filter;
/* SANITY */
sk_node_init(&newsk->sk_node);
- tcp_sk(newsk)->bind_hash = NULL;
+ newinet->bind_hash = NULL;
/* Clone the TCP header template */
- inet_sk(newsk)->dport = ireq->rmt_port;
+ newinet->dport = ireq->rmt_port;
sock_lock_init(newsk);
bh_lock_sock(newsk);
rwlock_init(&newsk->sk_dst_lock);
+ newsk->sk_dst_cache = NULL;
atomic_set(&newsk->sk_rmem_alloc, 0);
skb_queue_head_init(&newsk->sk_receive_queue);
atomic_set(&newsk->sk_wmem_alloc, 0);
newsk->sk_err = 0;
newsk->sk_priority = 0;
atomic_set(&newsk->sk_refcnt, 2);
-#ifdef INET_REFCNT_DEBUG
- atomic_inc(&inet_sock_nr);
-#endif
+
+ /*
+ * Increment the counter in the same struct proto as the master
+ * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
+ * is the same as sk->sk_prot->socks, as this field was copied
+ * with memcpy), same rationale as the first comment in this
+ * function.
+ *
+ * This _changes_ the previous behaviour, where
+ * tcp_create_openreq_child always was incrementing the
+ * equivalent to tcp_prot->socks (inet_sock_nr), so this have
+ * to be taken into account in all callers. -acme
+ */
+ sk_refcnt_debug_inc(newsk);
+
atomic_inc(&tcp_sockets_allocated);
if (sock_flag(newsk, SOCK_KEEPOPEN))