[NET]: Rework dev_base via list_head (v3)
Cleanup of dev_base list use, with the aim to simplify making device list per-namespace. In almost every occasion, use of dev_base variable and dev->next pointer could be easily replaced by for_each_netdev loop. A few most complicated places were converted to using first_netdev()/next_netdev(). Signed-off-by: Pavel Emelianov <xemul@openvz.org> Acked-by: Kirill Korotaev <dev@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Этот коммит содержится в:

коммит произвёл
David S. Miller

родитель
03fba04796
Коммит
7562f876cd
@@ -721,7 +721,7 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||
struct sock *sk = sock->sk;
|
||||
struct dn_scp *scp = DN_SK(sk);
|
||||
struct sockaddr_dn *saddr = (struct sockaddr_dn *)uaddr;
|
||||
struct net_device *dev;
|
||||
struct net_device *dev, *ldev;
|
||||
int rv;
|
||||
|
||||
if (addr_len != sizeof(struct sockaddr_dn))
|
||||
@@ -746,14 +746,17 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||
if (!(saddr->sdn_flags & SDF_WILD)) {
|
||||
if (dn_ntohs(saddr->sdn_nodeaddrl)) {
|
||||
read_lock(&dev_base_lock);
|
||||
for(dev = dev_base; dev; dev = dev->next) {
|
||||
ldev = NULL;
|
||||
for_each_netdev(dev) {
|
||||
if (!dev->dn_ptr)
|
||||
continue;
|
||||
if (dn_dev_islocal(dev, dn_saddr2dn(saddr)))
|
||||
if (dn_dev_islocal(dev, dn_saddr2dn(saddr))) {
|
||||
ldev = dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
read_unlock(&dev_base_lock);
|
||||
if (dev == NULL)
|
||||
if (ldev == NULL)
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
}
|
||||
|
@@ -799,9 +799,10 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
skip_ndevs = cb->args[0];
|
||||
skip_naddr = cb->args[1];
|
||||
|
||||
for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
|
||||
idx = 0;
|
||||
for_each_netdev(dev) {
|
||||
if (idx < skip_ndevs)
|
||||
continue;
|
||||
goto cont;
|
||||
else if (idx > skip_ndevs) {
|
||||
/* Only skip over addresses for first dev dumped
|
||||
* in this iteration (idx == skip_ndevs) */
|
||||
@@ -809,18 +810,20 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
}
|
||||
|
||||
if ((dn_db = dev->dn_ptr) == NULL)
|
||||
continue;
|
||||
goto cont;
|
||||
|
||||
for (ifa = dn_db->ifa_list, dn_idx = 0; ifa;
|
||||
ifa = ifa->ifa_next, dn_idx++) {
|
||||
if (dn_idx < skip_naddr)
|
||||
continue;
|
||||
goto cont;
|
||||
|
||||
if (dn_nl_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
|
||||
cb->nlh->nlmsg_seq, RTM_NEWADDR,
|
||||
NLM_F_MULTI) < 0)
|
||||
goto done;
|
||||
}
|
||||
cont:
|
||||
idx++;
|
||||
}
|
||||
done:
|
||||
cb->args[0] = idx;
|
||||
@@ -1296,7 +1299,7 @@ void dn_dev_devices_off(void)
|
||||
struct net_device *dev;
|
||||
|
||||
rtnl_lock();
|
||||
for(dev = dev_base; dev; dev = dev->next)
|
||||
for_each_netdev(dev)
|
||||
dn_dev_down(dev);
|
||||
rtnl_unlock();
|
||||
|
||||
@@ -1307,7 +1310,7 @@ void dn_dev_devices_on(void)
|
||||
struct net_device *dev;
|
||||
|
||||
rtnl_lock();
|
||||
for(dev = dev_base; dev; dev = dev->next) {
|
||||
for_each_netdev(dev) {
|
||||
if (dev->flags & IFF_UP)
|
||||
dn_dev_up(dev);
|
||||
}
|
||||
@@ -1325,62 +1328,56 @@ int unregister_dnaddr_notifier(struct notifier_block *nb)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static inline struct net_device *dn_dev_get_next(struct seq_file *seq, struct net_device *dev)
|
||||
static inline int is_dn_dev(struct net_device *dev)
|
||||
{
|
||||
do {
|
||||
dev = dev->next;
|
||||
} while(dev && !dev->dn_ptr);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static struct net_device *dn_dev_get_idx(struct seq_file *seq, loff_t pos)
|
||||
{
|
||||
struct net_device *dev;
|
||||
|
||||
dev = dev_base;
|
||||
if (dev && !dev->dn_ptr)
|
||||
dev = dn_dev_get_next(seq, dev);
|
||||
if (pos) {
|
||||
while(dev && (dev = dn_dev_get_next(seq, dev)))
|
||||
--pos;
|
||||
}
|
||||
return dev;
|
||||
return dev->dn_ptr != NULL;
|
||||
}
|
||||
|
||||
static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
if (*pos) {
|
||||
struct net_device *dev;
|
||||
read_lock(&dev_base_lock);
|
||||
dev = dn_dev_get_idx(seq, *pos - 1);
|
||||
if (dev == NULL)
|
||||
read_unlock(&dev_base_lock);
|
||||
return dev;
|
||||
int i;
|
||||
struct net_device *dev;
|
||||
|
||||
read_lock(&dev_base_lock);
|
||||
|
||||
if (*pos == 0)
|
||||
return SEQ_START_TOKEN;
|
||||
|
||||
i = 1;
|
||||
for_each_netdev(dev) {
|
||||
if (!is_dn_dev(dev))
|
||||
continue;
|
||||
|
||||
if (i++ == *pos)
|
||||
return dev;
|
||||
}
|
||||
return SEQ_START_TOKEN;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
struct net_device *dev = v;
|
||||
loff_t one = 1;
|
||||
struct net_device *dev;
|
||||
|
||||
if (v == SEQ_START_TOKEN) {
|
||||
dev = dn_dev_seq_start(seq, &one);
|
||||
} else {
|
||||
dev = dn_dev_get_next(seq, dev);
|
||||
if (dev == NULL)
|
||||
read_unlock(&dev_base_lock);
|
||||
}
|
||||
++*pos;
|
||||
return dev;
|
||||
|
||||
dev = (struct net_device *)v;
|
||||
if (v == SEQ_START_TOKEN)
|
||||
dev = net_device_entry(&dev_base_head);
|
||||
|
||||
for_each_netdev_continue(dev) {
|
||||
if (!is_dn_dev(dev))
|
||||
continue;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void dn_dev_seq_stop(struct seq_file *seq, void *v)
|
||||
{
|
||||
if (v && v != SEQ_START_TOKEN)
|
||||
read_unlock(&dev_base_lock);
|
||||
read_unlock(&dev_base_lock);
|
||||
}
|
||||
|
||||
static char *dn_type2asc(char type)
|
||||
|
@@ -602,7 +602,7 @@ static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa)
|
||||
|
||||
/* Scan device list */
|
||||
read_lock(&dev_base_lock);
|
||||
for(dev = dev_base; dev; dev = dev->next) {
|
||||
for_each_netdev(dev) {
|
||||
dn_db = dev->dn_ptr;
|
||||
if (dn_db == NULL)
|
||||
continue;
|
||||
|
@@ -886,7 +886,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
|
||||
.iif = loopback_dev.ifindex,
|
||||
.oif = oldflp->oif };
|
||||
struct dn_route *rt = NULL;
|
||||
struct net_device *dev_out = NULL;
|
||||
struct net_device *dev_out = NULL, *dev;
|
||||
struct neighbour *neigh = NULL;
|
||||
unsigned hash;
|
||||
unsigned flags = 0;
|
||||
@@ -925,15 +925,17 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
|
||||
goto out;
|
||||
}
|
||||
read_lock(&dev_base_lock);
|
||||
for(dev_out = dev_base; dev_out; dev_out = dev_out->next) {
|
||||
if (!dev_out->dn_ptr)
|
||||
for_each_netdev(dev) {
|
||||
if (!dev->dn_ptr)
|
||||
continue;
|
||||
if (!dn_dev_islocal(dev_out, oldflp->fld_src))
|
||||
if (!dn_dev_islocal(dev, oldflp->fld_src))
|
||||
continue;
|
||||
if ((dev_out->flags & IFF_LOOPBACK) &&
|
||||
if ((dev->flags & IFF_LOOPBACK) &&
|
||||
oldflp->fld_dst &&
|
||||
!dn_dev_islocal(dev_out, oldflp->fld_dst))
|
||||
!dn_dev_islocal(dev, oldflp->fld_dst))
|
||||
continue;
|
||||
|
||||
dev_out = dev;
|
||||
break;
|
||||
}
|
||||
read_unlock(&dev_base_lock);
|
||||
|
Ссылка в новой задаче
Block a user