This patch changes sdp to use Linux native lists for the listen conn
list.  The first version had a bug where if the listen list was empty,
the lookup would return a bogus conn.

Signed-off-by: Tom Duffy <[EMAIL PROTECTED]>

Index: linux-2.6.12-openib/drivers/infiniband/ulp/sdp/sdp_conn.c
===================================================================
--- linux-2.6.12-openib/drivers/infiniband/ulp/sdp/sdp_conn.c   (revision 2763)
+++ linux-2.6.12-openib/drivers/infiniband/ulp/sdp/sdp_conn.c   (working copy)
@@ -291,21 +291,11 @@ int sdp_inet_listen_start(struct sdp_soc
        conn->state  = SDP_CONN_ST_LISTEN;
        conn->accept_next = conn;
        conn->accept_prev = conn;
-       /*
-        * table lock
-        */
-       spin_lock_irqsave(&dev_root_s.listen_lock, flags);
-       /*
-        * insert into listening list.
-        */
-       conn->lstn_next = dev_root_s.listen_list;
-       dev_root_s.listen_list = conn;
-       conn->lstn_p_next = &dev_root_s.listen_list;
-
-       if (conn->lstn_next)
-               conn->lstn_next->lstn_p_next = &conn->lstn_next;
 
+       spin_lock_irqsave(&dev_root_s.listen_lock, flags);
+       list_add(&conn->lstn_next, &dev_root_s.listen_list);
        spin_unlock_irqrestore(&dev_root_s.listen_lock, flags);
+
        return 0;
 }
 
@@ -323,22 +313,11 @@ int sdp_inet_listen_stop(struct sdp_sock
        }
 
        listen_conn->state  = SDP_CONN_ST_CLOSED;
-       /*
-        * table lock
-        */
-       spin_lock_irqsave(&dev_root_s.listen_lock, flags);
-       /*
-        * remove from listening list.
-        */
-       if (listen_conn->lstn_next)
-               listen_conn->lstn_next->lstn_p_next = listen_conn->lstn_p_next;
-
-       *(listen_conn->lstn_p_next) = listen_conn->lstn_next;
-
-       listen_conn->lstn_p_next = NULL;
-       listen_conn->lstn_next = NULL;
 
+       spin_lock_irqsave(&dev_root_s.listen_lock, flags);
+       list_del(&listen_conn->lstn_next);
        spin_unlock_irqrestore(&dev_root_s.listen_lock, flags);
+
        /*
         * reject and delete all pending connections
         */
@@ -367,7 +346,7 @@ int sdp_inet_listen_stop(struct sdp_sock
  */
 struct sdp_sock *sdp_inet_listen_lookup(u32 addr, u16 port)
 {
-       struct sdp_sock *conn;
+       struct sdp_sock *conn, *ret = NULL;
        unsigned long flags;
        /*
         * table lock
@@ -376,15 +355,16 @@ struct sdp_sock *sdp_inet_listen_lookup(
        /*
         * first find a listening connection
         */
-       for (conn = dev_root_s.listen_list; conn; conn = conn->lstn_next)
+       list_for_each_entry(conn, &dev_root_s.listen_list, lstn_next)
                if (port == conn->src_port &&
                    (INADDR_ANY == conn->src_addr || addr == conn->src_addr)) {
                        sdp_conn_hold(conn);
+                       ret = conn;
                        break;
                }
 
        spin_unlock_irqrestore(&dev_root_s.listen_lock, flags);
-       return conn;
+       return ret;
 }
 
 /*
@@ -1936,7 +1916,7 @@ int sdp_conn_table_init(int proto_family
        /*
         * list
         */
-       dev_root_s.listen_list = NULL;
+       INIT_LIST_HEAD(&dev_root_s.listen_list);
        dev_root_s.bind_list = NULL;
 
        spin_lock_init(&dev_root_s.sock_lock);
Index: linux-2.6.12-openib/drivers/infiniband/ulp/sdp/sdp_conn.h
===================================================================
--- linux-2.6.12-openib/drivers/infiniband/ulp/sdp/sdp_conn.h   (revision 2763)
+++ linux-2.6.12-openib/drivers/infiniband/ulp/sdp/sdp_conn.h   (working copy)
@@ -36,6 +36,8 @@
 #ifndef _SDP_CONN_H
 #define _SDP_CONN_H
 
+#include <linux/list.h>
+
 #include "sdp_advt.h"
 #include "sdp_iocb.h"
 #include "sdp_dev.h"
@@ -336,8 +338,7 @@ struct sdp_sock {
        /*
         * table managment
         */
-       struct sdp_sock *lstn_next;    /* next conn in the chain */
-       struct sdp_sock **lstn_p_next; /* previous next conn in the chain */
+       struct list_head lstn_next;
 
        struct sdp_sock *bind_next;    /* next conn in the chain */
        struct sdp_sock **bind_p_next; /* previous next conn in the chain */
Index: linux-2.6.12-openib/drivers/infiniband/ulp/sdp/sdp_dev.h
===================================================================
--- linux-2.6.12-openib/drivers/infiniband/ulp/sdp/sdp_dev.h    (revision 2763)
+++ linux-2.6.12-openib/drivers/infiniband/ulp/sdp/sdp_dev.h    (working copy)
@@ -43,6 +43,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
+#include <linux/list.h>
 #include <net/sock.h>
 /*
  * sdp types
@@ -186,7 +187,7 @@ struct sdev_root {
        /*
         * connection managment
         */
-       struct sdp_sock *listen_list;   /* list of listening connections */
+       struct list_head listen_list;
        struct sdp_sock *bind_list;     /* connections bound to a port. */
        /*
         * list locks

_______________________________________________
openib-general mailing list
openib-general@openib.org
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to