Convert the custom hash list traversals to use hlist functions.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
        return (h & (sctp_assoc_hashsize-1));
 }
 
+#define sctp_for_each_hentry(epb, node, head) \
+       hlist_for_each_entry(epb, node, head, node)
+
 /* Is a socket of this style? */
 #define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style))
 static inline int __sctp_style(const struct sock *sk, sctp_socket_type_t style)
 
 struct sctp_bind_bucket {
        unsigned short  port;
        unsigned short  fastreuse;
-       struct sctp_bind_bucket *next;
-       struct sctp_bind_bucket **pprev;
+       struct hlist_node       node;
        struct hlist_head       owner;
 };
 
 struct sctp_bind_hashbucket {
        spinlock_t      lock;
-       struct sctp_bind_bucket *chain;
+       struct hlist_head       chain;
 };
 
 /* Used for hashing all associations.  */
 struct sctp_hashbucket {
        rwlock_t        lock;
-       struct sctp_ep_common  *chain;
+       struct hlist_head       chain;
 } __attribute__((__aligned__(8)));
 
 
 
 struct sctp_ep_common {
        /* Fields to help us manage our entries in the hash tables. */
-       struct sctp_ep_common *next;
-       struct sctp_ep_common **pprev;
+       struct hlist_node node;
        int hashent;
 
        /* Runtime type information.  What kind of endpoint is this? */
 
        struct sctp_transport *t = NULL;
        struct sctp_hashbucket *head;
        struct sctp_ep_common *epb;
+       struct hlist_node *node;
        int hash;
        int rport;
 
        hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport);
        head = &sctp_assoc_hashtable[hash];
        read_lock(&head->lock);
-       for (epb = head->chain; epb; epb = epb->next) {
+       sctp_for_each_hentry(epb, node, &head->chain) {
                asoc = sctp_assoc(epb);
                if (asoc->ep != ep || rport != asoc->peer.port)
                        goto next;
 
 /* Insert endpoint into the hash table.  */
 static void __sctp_hash_endpoint(struct sctp_endpoint *ep)
 {
-       struct sctp_ep_common **epp;
        struct sctp_ep_common *epb;
        struct sctp_hashbucket *head;
 
        head = &sctp_ep_hashtable[epb->hashent];
 
        sctp_write_lock(&head->lock);
-       epp = &head->chain;
-       epb->next = *epp;
-       if (epb->next)
-               (*epp)->pprev = &epb->next;
-       *epp = epb;
-       epb->pprev = epp;
+       hlist_add_head(&epb->node, &head->chain);
        sctp_write_unlock(&head->lock);
 }
 
 
        epb = &ep->base;
 
+       if (hlist_unhashed(&epb->node))
+               return;
+
        epb->hashent = sctp_ep_hashfn(epb->bind_addr.port);
 
        head = &sctp_ep_hashtable[epb->hashent];
 
        sctp_write_lock(&head->lock);
-
-       if (epb->pprev) {
-               if (epb->next)
-                       epb->next->pprev = epb->pprev;
-               *epb->pprev = epb->next;
-               epb->pprev = NULL;
-       }
-
+       __hlist_del(&epb->node);
        sctp_write_unlock(&head->lock);
 }
 
        struct sctp_hashbucket *head;
        struct sctp_ep_common *epb;
        struct sctp_endpoint *ep;
+       struct hlist_node *node;
        int hash;
 
        hash = sctp_ep_hashfn(ntohs(laddr->v4.sin_port));
        head = &sctp_ep_hashtable[hash];
        read_lock(&head->lock);
-       for (epb = head->chain; epb; epb = epb->next) {
+       sctp_for_each_hentry(epb, node, &head->chain) {
                ep = sctp_ep(epb);
                if (sctp_endpoint_is_match(ep, laddr))
                        goto hit;
 /* Insert association into the hash table.  */
 static void __sctp_hash_established(struct sctp_association *asoc)
 {
-       struct sctp_ep_common **epp;
        struct sctp_ep_common *epb;
        struct sctp_hashbucket *head;
 
        head = &sctp_assoc_hashtable[epb->hashent];
 
        sctp_write_lock(&head->lock);
-       epp = &head->chain;
-       epb->next = *epp;
-       if (epb->next)
-               (*epp)->pprev = &epb->next;
-       *epp = epb;
-       epb->pprev = epp;
+       hlist_add_head(&epb->node, &head->chain);
        sctp_write_unlock(&head->lock);
 }
 
        head = &sctp_assoc_hashtable[epb->hashent];
 
        sctp_write_lock(&head->lock);
-
-       if (epb->pprev) {
-               if (epb->next)
-                       epb->next->pprev = epb->pprev;
-               *epb->pprev = epb->next;
-               epb->pprev = NULL;
-       }
-
+       __hlist_del(&epb->node);
        sctp_write_unlock(&head->lock);
 }
 
        struct sctp_ep_common *epb;
        struct sctp_association *asoc;
        struct sctp_transport *transport;
+       struct hlist_node *node;
        int hash;
 
        /* Optimize here for direct hit, only listening connections can
        hash = sctp_assoc_hashfn(ntohs(local->v4.sin_port), ntohs(peer->v4.sin_port));
        head = &sctp_assoc_hashtable[hash];
        read_lock(&head->lock);
-       for (epb = head->chain; epb; epb = epb->next) {
+       sctp_for_each_hentry(epb, node, &head->chain) {
                asoc = sctp_assoc(epb);
                transport = sctp_assoc_is_match(asoc, local, peer);
                if (transport)
 
        struct sctp_ep_common *epb;
        struct sctp_endpoint *ep;
        struct sock *sk;
+       struct hlist_node *node;
        int    hash = *(loff_t *)v;
 
        if (hash >= sctp_ep_hashsize)
        head = &sctp_ep_hashtable[hash];
        sctp_local_bh_disable();
        read_lock(&head->lock);
-       for (epb = head->chain; epb; epb = epb->next) {
+       sctp_for_each_hentry(epb, node, &head->chain) {
                ep = sctp_ep(epb);
                sk = epb->sk;
                seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk,
        struct sctp_ep_common *epb;
        struct sctp_association *assoc;
        struct sock *sk;
+       struct hlist_node *node;
        int    hash = *(loff_t *)v;
 
        if (hash >= sctp_assoc_hashsize)
        head = &sctp_assoc_hashtable[hash];
        sctp_local_bh_disable();
        read_lock(&head->lock);
-       for (epb = head->chain; epb; epb = epb->next) {
+       sctp_for_each_hentry(epb, node, &head->chain) {
                assoc = sctp_assoc(epb);
                sk = epb->sk;
                seq_printf(seq,
 
        }
        for (i = 0; i < sctp_assoc_hashsize; i++) {
                rwlock_init(&sctp_assoc_hashtable[i].lock);
-               sctp_assoc_hashtable[i].chain = NULL;
+               INIT_HLIST_HEAD(&sctp_assoc_hashtable[i].chain);
        }
 
        /* Allocate and initialize the endpoint hash table.  */
        }
        for (i = 0; i < sctp_ep_hashsize; i++) {
                rwlock_init(&sctp_ep_hashtable[i].lock);
-               sctp_ep_hashtable[i].chain = NULL;
+               INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain);
        }
 
        /* Allocate and initialize the SCTP port hash table.  */
        }
        for (i = 0; i < sctp_port_hashsize; i++) {
                spin_lock_init(&sctp_port_hashtable[i].lock);
-               sctp_port_hashtable[i].chain = NULL;
+               INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain);
        }
 
        printk(KERN_INFO "SCTP: Hash tables configured "
 
 {
        struct sctp_bind_hashbucket *head; /* hash list */
        struct sctp_bind_bucket *pp; /* hash list port iterator */
+       struct hlist_node *node;
        unsigned short snum;
        int ret;
 
                        index = sctp_phashfn(rover);
                        head = &sctp_port_hashtable[index];
                        sctp_spin_lock(&head->lock);
-                       for (pp = head->chain; pp; pp = pp->next)
+                       sctp_for_each_hentry(pp, node, &head->chain)
                                if (pp->port == rover)
                                        goto next;
                        break;
                 */
                head = &sctp_port_hashtable[sctp_phashfn(snum)];
                sctp_spin_lock(&head->lock);
-               for (pp = head->chain; pp; pp = pp->next) {
+               sctp_for_each_hentry(pp, node, &head->chain) {
                        if (pp->port == snum)
                                goto pp_found;
                }
                pp->port = snum;
                pp->fastreuse = 0;
                INIT_HLIST_HEAD(&pp->owner);
-               if ((pp->next = head->chain) != NULL)
-                       pp->next->pprev = &pp->next;
-               head->chain = pp;
-               pp->pprev = &head->chain;
+               hlist_add_head(&pp->node, &head->chain);
        }
        return pp;
 }
 static void sctp_bucket_destroy(struct sctp_bind_bucket *pp)
 {
        if (pp && hlist_empty(&pp->owner)) {
-               if (pp->next)
-                       pp->next->pprev = pp->pprev;
-               *(pp->pprev) = pp->next;
+               __hlist_del(&pp->node);
                kmem_cache_free(sctp_bucket_cachep, pp);
                SCTP_DBG_OBJCNT_DEC(bind_bucket);
        }