o ipx: convert ipx_route to use list_head

parent fb4b4a84
...@@ -75,7 +75,7 @@ struct ipx_route { ...@@ -75,7 +75,7 @@ struct ipx_route {
struct ipx_interface *ir_intrfc; struct ipx_interface *ir_intrfc;
unsigned char ir_routed; unsigned char ir_routed;
unsigned char ir_router_node[IPX_NODE_LEN]; 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; atomic_t refcnt;
}; };
...@@ -111,7 +111,7 @@ struct ipx_opt { ...@@ -111,7 +111,7 @@ struct ipx_opt {
#define IPX_MIN_EPHEMERAL_SOCKET 0x4000 #define IPX_MIN_EPHEMERAL_SOCKET 0x4000
#define IPX_MAX_EPHEMERAL_SOCKET 0x7fff #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 rwlock_t ipx_routes_lock;
extern struct list_head ipx_interfaces; extern struct list_head ipx_interfaces;
......
...@@ -81,7 +81,7 @@ static struct datalink_proto *pSNAP_datalink; ...@@ -81,7 +81,7 @@ static struct datalink_proto *pSNAP_datalink;
static struct proto_ops ipx_dgram_ops; static struct proto_ops ipx_dgram_ops;
struct ipx_route *ipx_routes; LIST_HEAD(ipx_routes);
rwlock_t ipx_routes_lock = RW_LOCK_UNLOCKED; rwlock_t ipx_routes_lock = RW_LOCK_UNLOCKED;
LIST_HEAD(ipx_interfaces); LIST_HEAD(ipx_interfaces);
...@@ -1277,12 +1277,14 @@ static struct ipx_route *ipxrtr_lookup(__u32 net) ...@@ -1277,12 +1277,14 @@ static struct ipx_route *ipxrtr_lookup(__u32 net)
struct ipx_route *r; struct ipx_route *r;
read_lock_bh(&ipx_routes_lock); read_lock_bh(&ipx_routes_lock);
for (r = ipx_routes; r && r->ir_net != net; r = r->ir_next) list_for_each_entry(r, &ipx_routes, node)
; if (r->ir_net == net) {
if (r)
ipxrtr_hold(r); ipxrtr_hold(r);
goto unlock;
}
r = NULL;
unlock:
read_unlock_bh(&ipx_routes_lock); read_unlock_bh(&ipx_routes_lock);
return r; return r;
} }
...@@ -1305,8 +1307,7 @@ static int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc, ...@@ -1305,8 +1307,7 @@ static int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc,
atomic_set(&rt->refcnt, 1); atomic_set(&rt->refcnt, 1);
ipxrtr_hold(rt); ipxrtr_hold(rt);
write_lock_bh(&ipx_routes_lock); write_lock_bh(&ipx_routes_lock);
rt->ir_next = ipx_routes; list_add(&rt->node, &ipx_routes);
ipx_routes = rt;
write_unlock_bh(&ipx_routes_lock); write_unlock_bh(&ipx_routes_lock);
} else { } else {
rc = -EEXIST; rc = -EEXIST;
...@@ -1333,15 +1334,13 @@ static int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc, ...@@ -1333,15 +1334,13 @@ static int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc,
static void ipxrtr_del_routes(struct ipx_interface *intrfc) 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); write_lock_bh(&ipx_routes_lock);
for (r = &ipx_routes; (tmp = *r) != NULL;) { list_for_each_entry_safe(r, tmp, &ipx_routes, node)
if (tmp->ir_intrfc == intrfc) { if (r->ir_intrfc == intrfc) {
*r = tmp->ir_next; list_del(&r->node);
ipxrtr_put(tmp); ipxrtr_put(r);
} else
r = &(tmp->ir_next);
} }
write_unlock_bh(&ipx_routes_lock); write_unlock_bh(&ipx_routes_lock);
} }
...@@ -1363,26 +1362,21 @@ static int ipxrtr_create(struct ipx_route_definition *rd) ...@@ -1363,26 +1362,21 @@ static int ipxrtr_create(struct ipx_route_definition *rd)
static int ipxrtr_delete(long net) static int ipxrtr_delete(long net)
{ {
struct ipx_route **r; struct ipx_route *r, *tmp;
struct ipx_route *tmp;
int rc; int rc;
write_lock_bh(&ipx_routes_lock); write_lock_bh(&ipx_routes_lock);
for (r = &ipx_routes; (tmp = *r) != NULL;) { list_for_each_entry_safe(r, tmp, &ipx_routes, node)
if (tmp->ir_net == net) { if (r->ir_net == net) {
/* Directly connected; can't lose route */ /* Directly connected; can't lose route */
rc = -EPERM; rc = -EPERM;
if (!tmp->ir_routed) if (!r->ir_routed)
goto out; goto out;
list_del(&r->node);
*r = tmp->ir_next; ipxrtr_put(r);
ipxrtr_put(tmp);
rc = 0; rc = 0;
goto out; goto out;
} }
r = &(tmp->ir_next);
}
rc = -ENOENT; rc = -ENOENT;
out: out:
write_unlock_bh(&ipx_routes_lock); write_unlock_bh(&ipx_routes_lock);
......
...@@ -89,13 +89,33 @@ static int ipx_seq_interface_show(struct seq_file *seq, void *v) ...@@ -89,13 +89,33 @@ static int ipx_seq_interface_show(struct seq_file *seq, void *v)
return 0; 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) static __inline__ struct ipx_route *ipx_get_route_idx(loff_t pos)
{ {
struct ipx_route *r; struct ipx_route *r;
for (r = ipx_routes; pos && r; r = r->ir_next) list_for_each_entry(r, &ipx_routes, node)
--pos; if (!pos--)
goto out;
r = NULL;
out:
return r; return r;
} }
...@@ -111,15 +131,10 @@ static void *ipx_seq_route_next(struct seq_file *seq, void *v, loff_t *pos) ...@@ -111,15 +131,10 @@ static void *ipx_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
struct ipx_route *r; struct ipx_route *r;
++*pos; ++*pos;
if (v == (void *)1) { if (v == (void *)1)
r = NULL; r = ipx_routes_head();
if (ipx_routes) else
r = ipx_routes; r = ipx_routes_next(v);
goto out;
}
r = v;
r = r->ir_next;
out:
return r; return r;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment