o ipx: convert ipx_interface handling to use list_head

parent 277110dc
......@@ -12,6 +12,7 @@
#include <linux/netdevice.h>
#include <net/datalink.h>
#include <linux/ipx.h>
#include <linux/list.h>
struct ipx_address {
__u32 net;
......@@ -66,7 +67,7 @@ struct ipx_interface {
unsigned char if_internal;
unsigned char if_primary;
struct ipx_interface *if_next;
struct list_head node; /* node in ipx_interfaces list */
};
struct ipx_route {
......@@ -113,7 +114,8 @@ struct ipx_opt {
extern struct ipx_route *ipx_routes;
extern rwlock_t ipx_routes_lock;
extern struct ipx_interface *ipx_interfaces;
extern struct list_head ipx_interfaces;
extern struct ipx_interface *ipx_interfaces_head(void);
extern spinlock_t ipx_interfaces_lock;
extern struct ipx_interface *ipx_primary_net;
......
......@@ -84,7 +84,7 @@ static struct proto_ops ipx_dgram_ops;
struct ipx_route *ipx_routes;
rwlock_t ipx_routes_lock = RW_LOCK_UNLOCKED;
struct ipx_interface *ipx_interfaces;
LIST_HEAD(ipx_interfaces);
spinlock_t ipx_interfaces_lock = SPIN_LOCK_UNLOCKED;
struct ipx_interface *ipx_primary_net;
......@@ -95,11 +95,21 @@ static struct ipx_interface *ipx_internal_net;
atomic_t ipx_sock_nr;
#endif
struct ipx_interface *ipx_interfaces_head(void)
{
struct ipx_interface *rc = NULL;
if (!list_empty(&ipx_interfaces))
rc = list_entry(ipx_interfaces.next,
struct ipx_interface, node);
return rc;
}
static void ipxcfg_set_auto_select(char val)
{
ipxcfg_auto_select_primary = val;
if (val && !ipx_primary_net)
ipx_primary_net = ipx_interfaces;
ipx_primary_net = ipx_interfaces_head();
}
static int ipxcfg_get_config_data(struct ipx_config_data *arg)
......@@ -197,17 +207,21 @@ static struct ipx_route *ipxrtr_lookup(__u32 net);
static void ipxitf_clear_primary_net(void)
{
ipx_primary_net = ipxcfg_auto_select_primary ? ipx_interfaces : NULL;
ipx_primary_net = NULL;
if (ipxcfg_auto_select_primary)
ipx_primary_net = ipx_interfaces_head();
}
static struct ipx_interface *__ipxitf_find_using_phys(struct net_device *dev,
unsigned short datalink)
{
struct ipx_interface *i = ipx_interfaces;
while (i && (i->if_dev != dev || i->if_dlink_type != datalink))
i = i->if_next;
struct ipx_interface *i;
list_for_each_entry(i, &ipx_interfaces, node)
if (i->if_dev == dev && i->if_dlink_type == datalink)
goto out;
i = NULL;
out:
return i;
}
......@@ -229,16 +243,20 @@ static struct ipx_interface *ipxitf_find_using_net(__u32 net)
struct ipx_interface *i;
spin_lock_bh(&ipx_interfaces_lock);
if (net)
for (i = ipx_interfaces; i && i->if_netnum != net;
i = i->if_next)
;
else
i = ipx_primary_net;
if (net) {
list_for_each_entry(i, &ipx_interfaces, node)
if (i->if_netnum == net)
goto hold;
i = NULL;
goto unlock;
}
i = ipx_primary_net;
if (i)
hold:
ipxitf_hold(i);
unlock:
spin_unlock_bh(&ipx_interfaces_lock);
return i;
}
......@@ -342,15 +360,7 @@ static void __ipxitf_down(struct ipx_interface *intrfc)
spin_unlock_bh(&intrfc->if_sklist_lock);
/* remove this interface from list */
if (intrfc == ipx_interfaces)
ipx_interfaces = intrfc->if_next;
else {
struct ipx_interface *i = ipx_interfaces;
while (i && i->if_next != intrfc)
i = i->if_next;
if (i && i->if_next == intrfc)
i->if_next = intrfc->if_next;
}
list_del(&intrfc->node);
/* remove this interface from *special* networks */
if (intrfc == ipx_primary_net)
......@@ -380,16 +390,13 @@ static int ipxitf_device_event(struct notifier_block *notifier,
goto out;
spin_lock_bh(&ipx_interfaces_lock);
for (i = ipx_interfaces; i;) {
tmp = i->if_next;
list_for_each_entry_safe(i, tmp, &ipx_interfaces, node)
if (i->if_dev == dev) {
if (event == NETDEV_UP)
ipxitf_hold(i);
else
__ipxitf_put(i);
}
i = tmp;
}
spin_unlock_bh(&ipx_interfaces_lock);
out:
return NOTIFY_DONE;
......@@ -872,7 +879,7 @@ static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb)
IPX_SKB_CB(skb)->last_hop.netnum = intrfc->if_netnum;
/* xmit on all other interfaces... */
spin_lock_bh(&ipx_interfaces_lock);
for (ifcs = ipx_interfaces; ifcs; ifcs = ifcs->if_next) {
list_for_each_entry(ifcs, &ipx_interfaces, node) {
/* Except unconfigured interfaces */
if (!ifcs->if_netnum)
continue;
......@@ -902,16 +909,8 @@ static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb)
static void ipxitf_insert(struct ipx_interface *intrfc)
{
intrfc->if_next = NULL;
spin_lock_bh(&ipx_interfaces_lock);
if (!ipx_interfaces)
ipx_interfaces = intrfc;
else {
struct ipx_interface *i = ipx_interfaces;
while (i->if_next)
i = i->if_next;
i->if_next = intrfc;
}
list_add_tail(&intrfc->node, &ipx_interfaces);
spin_unlock_bh(&ipx_interfaces_lock);
if (ipxcfg_auto_select_primary && !ipx_primary_net)
......
......@@ -17,12 +17,23 @@ static __inline__ struct ipx_interface *ipx_get_interface_idx(loff_t pos)
{
struct ipx_interface *i;
for (i = ipx_interfaces; pos && i; i = i->if_next)
--pos;
list_for_each_entry(i, &ipx_interfaces, node)
if (!pos--)
goto out;
i = NULL;
out:
return i;
}
static struct ipx_interface *ipx_interfaces_next(struct ipx_interface *i)
{
struct ipx_interface *rc = NULL;
if (i->node.next != &ipx_interfaces)
rc = list_entry(i->node.next, struct ipx_interface, node);
return rc;
}
static void *ipx_seq_interface_start(struct seq_file *seq, loff_t *pos)
{
loff_t l = *pos;
......@@ -36,15 +47,10 @@ static void *ipx_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
struct ipx_interface *i;
++*pos;
if (v == (void *)1) {
i = NULL;
if (ipx_interfaces)
i = ipx_interfaces;
goto out;
}
i = v;
i = i->if_next;
out:
if (v == (void *)1)
i = ipx_interfaces_head();
else
i = ipx_interfaces_next(v);
return i;
}
......@@ -149,7 +155,9 @@ static __inline__ struct sock *ipx_get_socket_idx(loff_t pos)
struct sock *s = NULL;
struct ipx_interface *i;
for (i = ipx_interfaces; pos && i; i = i->if_next) {
list_for_each_entry(i, &ipx_interfaces, node) {
if (!pos)
break;
spin_lock_bh(&i->if_sklist_lock);
for (s = i->if_sklist; pos && s; s = s->next)
--pos;
......@@ -181,11 +189,12 @@ static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
++*pos;
if (v == (void *)1) {
sk = NULL;
if (!ipx_interfaces)
i = ipx_interfaces_head();
if (!i)
goto out;
sk = ipx_interfaces->if_sklist;
sk = i->if_sklist;
if (sk)
spin_lock_bh(&ipx_interfaces->if_sklist_lock);
spin_lock_bh(&i->if_sklist_lock);
goto out;
}
sk = v;
......@@ -198,9 +207,9 @@ static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
spin_unlock_bh(&i->if_sklist_lock);
sk = NULL;
for (;;) {
if (!i->if_next)
i = ipx_interfaces_next(i);
if (!i)
break;
i = i->if_next;
spin_lock_bh(&i->if_sklist_lock);
if (i->if_sklist) {
sk = i->if_sklist;
......
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