diff options
| author | Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 2003-05-05 14:18:41 -0300 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 2003-05-05 14:18:41 -0300 |
| commit | 975dc0dc390802114b5cd7b80c9c2f901c9fb2bb (patch) | |
| tree | 6ddcc30a4ff8a5d94d4423452e594a645512ea27 | |
| parent | fb4b4a84b0561ea4285ff7fb3d1391c8859fbb57 (diff) | |
o ipx: convert ipx_route to use list_head
| -rw-r--r-- | include/net/ipx.h | 4 | ||||
| -rw-r--r-- | net/ipx/af_ipx.c | 48 | ||||
| -rw-r--r-- | net/ipx/ipx_proc.c | 39 |
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; } |
