Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
[sfrench/cifs-2.6.git] / net / ipv4 / tcp.c
index 0eed64a1991db867711a638af46787921c15831f..f3f0013a95804808d1522e89192b0beaefa91a30 100644 (file)
 
 int sysctl_tcp_fin_timeout = TCP_FIN_TIMEOUT;
 
-DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics);
+DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics) __read_mostly;
 
 atomic_t tcp_orphan_count = ATOMIC_INIT(0);
 
@@ -309,15 +309,6 @@ void tcp_enter_memory_pressure(void)
 
 EXPORT_SYMBOL(tcp_enter_memory_pressure);
 
-/*
- * LISTEN is a special case for poll..
- */
-static __inline__ unsigned int tcp_listen_poll(struct sock *sk,
-                                              poll_table *wait)
-{
-       return !reqsk_queue_empty(&inet_csk(sk)->icsk_accept_queue) ? (POLLIN | POLLRDNORM) : 0;
-}
-
 /*
  *     Wait for a TCP event.
  *
@@ -333,7 +324,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
 
        poll_wait(file, sk->sk_sleep, wait);
        if (sk->sk_state == TCP_LISTEN)
-               return tcp_listen_poll(sk, wait);
+               return inet_csk_listen_poll(sk);
 
        /* Socket is not locked. We are protected from async events
           by poll logic and correct handling of state changes
@@ -561,8 +552,7 @@ new_segment:
                        tcp_mark_push(tp, skb);
                        goto new_segment;
                }
-               if (sk->sk_forward_alloc < copy &&
-                   !sk_stream_mem_schedule(sk, copy, 0))
+               if (!sk_stream_wmem_schedule(sk, copy))
                        goto wait_for_memory;
                
                if (can_coalesce) {
@@ -779,19 +769,23 @@ new_segment:
                                        if (off == PAGE_SIZE) {
                                                put_page(page);
                                                TCP_PAGE(sk) = page = NULL;
+                                               off = 0;
                                        }
-                               }
+                               } else
+                                       off = 0;
+
+                               if (copy > PAGE_SIZE - off)
+                                       copy = PAGE_SIZE - off;
+
+                               if (!sk_stream_wmem_schedule(sk, copy))
+                                       goto wait_for_memory;
 
                                if (!page) {
                                        /* Allocate new cache page. */
                                        if (!(page = sk_stream_alloc_page(sk)))
                                                goto wait_for_memory;
-                                       off = 0;
                                }
 
-                               if (copy > PAGE_SIZE - off)
-                                       copy = PAGE_SIZE - off;
-
                                /* Time to copy data. We are close to
                                 * the end! */
                                err = skb_copy_to_page(sk, from, skb, page,
@@ -1671,11 +1665,11 @@ int tcp_disconnect(struct sock *sk, int flags)
                tp->write_seq = 1;
        icsk->icsk_backoff = 0;
        tp->snd_cwnd = 2;
-       tp->probes_out = 0;
+       icsk->icsk_probes_out = 0;
        tp->packets_out = 0;
        tp->snd_ssthresh = 0x7fffffff;
        tp->snd_cwnd_cnt = 0;
-       tcp_set_ca_state(tp, TCP_CA_Open);
+       tcp_set_ca_state(sk, TCP_CA_Open);
        tcp_clear_retrans(tp);
        inet_csk_delack_init(sk);
        sk->sk_send_head = NULL;
@@ -1718,7 +1712,7 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
                name[val] = 0;
 
                lock_sock(sk);
-               err = tcp_set_congestion_control(tp, name);
+               err = tcp_set_congestion_control(sk, name);
                release_sock(sk);
                return err;
        }
@@ -1886,9 +1880,9 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
        memset(info, 0, sizeof(*info));
 
        info->tcpi_state = sk->sk_state;
-       info->tcpi_ca_state = tp->ca_state;
+       info->tcpi_ca_state = icsk->icsk_ca_state;
        info->tcpi_retransmits = icsk->icsk_retransmits;
-       info->tcpi_probes = tp->probes_out;
+       info->tcpi_probes = icsk->icsk_probes_out;
        info->tcpi_backoff = icsk->icsk_backoff;
 
        if (tp->rx_opt.tstamp_ok)
@@ -2016,7 +2010,7 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
                len = min_t(unsigned int, len, TCP_CA_NAME_MAX);
                if (put_user(len, optlen))
                        return -EFAULT;
-               if (copy_to_user(optval, tp->ca_ops->name, len))
+               if (copy_to_user(optval, icsk->icsk_ca_ops->name, len))
                        return -EFAULT;
                return 0;
        default: