tcp: accept socket after TCP_DEFER_ACCEPT period
[safe/jmp/linux-2.6] / net / ipv4 / inetpeer.c
index 771031d..b1fbe18 100644 (file)
@@ -3,8 +3,6 @@
  *
  *  This source is covered by the GNU GPL, the same as all kernel sources.
  *
- *  Version:   $Id: inetpeer.c,v 1.7 2001/09/20 21:22:50 davem Exp $
- *
  *  Authors:   Andrey V. Savochkin <saw@msu.ru>
  */
 
@@ -61,7 +59,7 @@
  *  4.  Global variable peer_total is modified under the pool lock.
  *  5.  struct inet_peer fields modification:
  *             avl_left, avl_right, avl_parent, avl_height: pool lock
- *             unused_next, unused_prevp: unused node list lock
+ *             unused: unused node list lock
  *             refcnt: atomically against modifications on other CPU;
  *                usually under some other lock to prevent node disappearing
  *             dtime: unused node list lock
@@ -94,8 +92,7 @@ int inet_peer_maxttl __read_mostly = 10 * 60 * HZ;    /* usual time to live: 10 min
 int inet_peer_gc_mintime __read_mostly = 10 * HZ;
 int inet_peer_gc_maxtime __read_mostly = 120 * HZ;
 
-static struct inet_peer *inet_peer_unused_head;
-static struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head;
+static LIST_HEAD(unused_peers);
 static DEFINE_SPINLOCK(inet_peer_unused_lock);
 
 static void peer_check_expire(unsigned long dummy);
@@ -138,15 +135,7 @@ void __init inet_initpeers(void)
 static void unlink_from_unused(struct inet_peer *p)
 {
        spin_lock_bh(&inet_peer_unused_lock);
-       if (p->unused_prevp != NULL) {
-               /* On unused list. */
-               *p->unused_prevp = p->unused_next;
-               if (p->unused_next != NULL)
-                       p->unused_next->unused_prevp = p->unused_prevp;
-               else
-                       inet_peer_unused_tailp = p->unused_prevp;
-               p->unused_prevp = NULL; /* mark it as removed */
-       }
+       list_del_init(&p->unused);
        spin_unlock_bh(&inet_peer_unused_lock);
 }
 
@@ -155,7 +144,7 @@ static void unlink_from_unused(struct inet_peer *p)
  * _stack is known to be NULL or not at compile time,
  * so compiler will optimize the if (_stack) tests.
  */
-#define lookup(_daddr,_stack)                                  \
+#define lookup(_daddr, _stack)                                         \
 ({                                                             \
        struct inet_peer *u, **v;                               \
        if (_stack != NULL) {                                   \
@@ -337,24 +326,24 @@ static void unlink_from_pool(struct inet_peer *p)
 /* May be called with local BH enabled. */
 static int cleanup_once(unsigned long ttl)
 {
-       struct inet_peer *p;
+       struct inet_peer *p = NULL;
 
        /* Remove the first entry from the list of unused nodes. */
        spin_lock_bh(&inet_peer_unused_lock);
-       p = inet_peer_unused_head;
-       if (p != NULL) {
-               __u32 delta = (__u32)jiffies - p->dtime;
+       if (!list_empty(&unused_peers)) {
+               __u32 delta;
+
+               p = list_first_entry(&unused_peers, struct inet_peer, unused);
+               delta = (__u32)jiffies - p->dtime;
+
                if (delta < ttl) {
                        /* Do not prune fresh entries. */
                        spin_unlock_bh(&inet_peer_unused_lock);
                        return -1;
                }
-               inet_peer_unused_head = p->unused_next;
-               if (p->unused_next != NULL)
-                       p->unused_next->unused_prevp = p->unused_prevp;
-               else
-                       inet_peer_unused_tailp = p->unused_prevp;
-               p->unused_prevp = NULL; /* mark as not on the list */
+
+               list_del_init(&p->unused);
+
                /* Grab an extra reference to prevent node disappearing
                 * before unlink_from_pool() call. */
                atomic_inc(&p->refcnt);
@@ -412,7 +401,7 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create)
 
        /* Link the node. */
        link_to_pool(n);
-       n->unused_prevp = NULL; /* not on the list */
+       INIT_LIST_HEAD(&n->unused);
        peer_total++;
        write_unlock_bh(&peer_pool_lock);
 
@@ -467,10 +456,7 @@ void inet_putpeer(struct inet_peer *p)
 {
        spin_lock_bh(&inet_peer_unused_lock);
        if (atomic_dec_and_test(&p->refcnt)) {
-               p->unused_prevp = inet_peer_unused_tailp;
-               p->unused_next = NULL;
-               *inet_peer_unused_tailp = p;
-               inet_peer_unused_tailp = &p->unused_next;
+               list_add_tail(&p->unused, &unused_peers);
                p->dtime = (__u32)jiffies;
        }
        spin_unlock_bh(&inet_peer_unused_lock);