summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@conectiva.com.br>2003-05-05 14:18:41 -0300
committerArnaldo Carvalho de Melo <acme@conectiva.com.br>2003-05-05 14:18:41 -0300
commit975dc0dc390802114b5cd7b80c9c2f901c9fb2bb (patch)
tree6ddcc30a4ff8a5d94d4423452e594a645512ea27
parentfb4b4a84b0561ea4285ff7fb3d1391c8859fbb57 (diff)
o ipx: convert ipx_route to use list_head
-rw-r--r--include/net/ipx.h4
-rw-r--r--net/ipx/af_ipx.c48
-rw-r--r--net/ipx/ipx_proc.c39
3 files changed, 50 insertions, 41 deletions
diff --git a/include/net/ipx.h b/include/net/ipx.h
index a588ad2428c1..864359402b31 100644
--- a/include/net/ipx.h
+++ b/include/net/ipx.h
@@ -75,7 +75,7 @@ struct ipx_route {
struct ipx_interface *ir_intrfc;
unsigned char ir_routed;
unsigned char ir_router_node[IPX_NODE_LEN];
- struct ipx_route *ir_next;
+ struct list_head node; /* node in ipx_routes list */
atomic_t refcnt;
};
@@ -111,7 +111,7 @@ struct ipx_opt {
#define IPX_MIN_EPHEMERAL_SOCKET 0x4000
#define IPX_MAX_EPHEMERAL_SOCKET 0x7fff
-extern struct ipx_route *ipx_routes;
+extern struct list_head ipx_routes;
extern rwlock_t ipx_routes_lock;
extern struct list_head ipx_interfaces;
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index bc700b19fde5..54161373137d 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -81,7 +81,7 @@ static struct datalink_proto *pSNAP_datalink;
static struct proto_ops ipx_dgram_ops;
-struct ipx_route *ipx_routes;
+LIST_HEAD(ipx_routes);
rwlock_t ipx_routes_lock = RW_LOCK_UNLOCKED;
LIST_HEAD(ipx_interfaces);
@@ -1277,12 +1277,14 @@ static struct ipx_route *ipxrtr_lookup(__u32 net)
struct ipx_route *r;
read_lock_bh(&ipx_routes_lock);
- for (r = ipx_routes; r && r->ir_net != net; r = r->ir_next)
- ;
- if (r)
- ipxrtr_hold(r);
+ list_for_each_entry(r, &ipx_routes, node)
+ if (r->ir_net == net) {
+ ipxrtr_hold(r);
+ goto unlock;
+ }
+ r = NULL;
+unlock:
read_unlock_bh(&ipx_routes_lock);
-
return r;
}
@@ -1305,8 +1307,7 @@ static int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc,
atomic_set(&rt->refcnt, 1);
ipxrtr_hold(rt);
write_lock_bh(&ipx_routes_lock);
- rt->ir_next = ipx_routes;
- ipx_routes = rt;
+ list_add(&rt->node, &ipx_routes);
write_unlock_bh(&ipx_routes_lock);
} else {
rc = -EEXIST;
@@ -1333,16 +1334,14 @@ out:
static void ipxrtr_del_routes(struct ipx_interface *intrfc)
{
- struct ipx_route **r, *tmp;
+ struct ipx_route *r, *tmp;
write_lock_bh(&ipx_routes_lock);
- for (r = &ipx_routes; (tmp = *r) != NULL;) {
- if (tmp->ir_intrfc == intrfc) {
- *r = tmp->ir_next;
- ipxrtr_put(tmp);
- } else
- r = &(tmp->ir_next);
- }
+ list_for_each_entry_safe(r, tmp, &ipx_routes, node)
+ if (r->ir_intrfc == intrfc) {
+ list_del(&r->node);
+ ipxrtr_put(r);
+ }
write_unlock_bh(&ipx_routes_lock);
}
@@ -1363,26 +1362,21 @@ out:
static int ipxrtr_delete(long net)
{
- struct ipx_route **r;
- struct ipx_route *tmp;
+ struct ipx_route *r, *tmp;
int rc;
write_lock_bh(&ipx_routes_lock);
- for (r = &ipx_routes; (tmp = *r) != NULL;) {
- if (tmp->ir_net == net) {
+ list_for_each_entry_safe(r, tmp, &ipx_routes, node)
+ if (r->ir_net == net) {
/* Directly connected; can't lose route */
rc = -EPERM;
- if (!tmp->ir_routed)
+ if (!r->ir_routed)
goto out;
-
- *r = tmp->ir_next;
- ipxrtr_put(tmp);
+ list_del(&r->node);
+ ipxrtr_put(r);
rc = 0;
goto out;
}
-
- r = &(tmp->ir_next);
- }
rc = -ENOENT;
out:
write_unlock_bh(&ipx_routes_lock);
diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c
index 08bb4ea97a13..8b854d146701 100644
--- a/net/ipx/ipx_proc.c
+++ b/net/ipx/ipx_proc.c
@@ -89,13 +89,33 @@ out:
return 0;
}
+static struct ipx_route *ipx_routes_head(void)
+{
+ struct ipx_route *rc = NULL;
+
+ if (!list_empty(&ipx_routes))
+ rc = list_entry(ipx_routes.next, struct ipx_route, node);
+ return rc;
+}
+
+static struct ipx_route *ipx_routes_next(struct ipx_route *r)
+{
+ struct ipx_route *rc = NULL;
+
+ if (r->node.next != &ipx_routes)
+ rc = list_entry(r->node.next, struct ipx_route, node);
+ return rc;
+}
+
static __inline__ struct ipx_route *ipx_get_route_idx(loff_t pos)
{
struct ipx_route *r;
- for (r = ipx_routes; pos && r; r = r->ir_next)
- --pos;
-
+ list_for_each_entry(r, &ipx_routes, node)
+ if (!pos--)
+ goto out;
+ r = NULL;
+out:
return r;
}
@@ -111,15 +131,10 @@ static void *ipx_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
struct ipx_route *r;
++*pos;
- if (v == (void *)1) {
- r = NULL;
- if (ipx_routes)
- r = ipx_routes;
- goto out;
- }
- r = v;
- r = r->ir_next;
-out:
+ if (v == (void *)1)
+ r = ipx_routes_head();
+ else
+ r = ipx_routes_next(v);
return r;
}