o ipx: convert ipx_route to use list_head

parent fb4b4a84
......@@ -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;
......
......@@ -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 @@ static int ipxrtr_add_route(__u32 network, 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);
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 @@ static int ipxrtr_create(struct ipx_route_definition *rd)
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);
......
......@@ -89,13 +89,33 @@ static int ipx_seq_interface_show(struct seq_file *seq, void *v)
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;
}
......
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