Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 171105
b: refs/heads/master
c: 72c9528
h: refs/heads/master
i:
  171103: 765f465
v: v3
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Nov 2, 2009
1 parent 13a726d commit 1c6768b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 68d8287ce1e1da3c99881385a93e74f68c454fc2
refs/heads/master: 72c9528bab94cc052d00ce241b8e85f5d71e45f0
1 change: 1 addition & 0 deletions trunk/include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,7 @@ extern void __dev_remove_pack(struct packet_type *pt);
extern struct net_device *dev_get_by_flags(struct net *net, unsigned short flags,
unsigned short mask);
extern struct net_device *dev_get_by_name(struct net *net, const char *name);
extern struct net_device *dev_get_by_name_rcu(struct net *net, const char *name);
extern struct net_device *__dev_get_by_name(struct net *net, const char *name);
extern int dev_alloc_name(struct net_device *dev, const char *name);
extern int dev_open(struct net_device *dev);
Expand Down
49 changes: 40 additions & 9 deletions trunk/net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ static int list_netdevice(struct net_device *dev)

write_lock_bh(&dev_base_lock);
list_add_tail(&dev->dev_list, &net->dev_base_head);
hlist_add_head(&dev->name_hlist, dev_name_hash(net, dev->name));
hlist_add_head_rcu(&dev->name_hlist, dev_name_hash(net, dev->name));
hlist_add_head_rcu(&dev->index_hlist,
dev_index_hash(net, dev->ifindex));
write_unlock_bh(&dev_base_lock);
Expand All @@ -230,7 +230,7 @@ static void unlist_netdevice(struct net_device *dev)
/* Unlink dev from the device chain */
write_lock_bh(&dev_base_lock);
list_del(&dev->dev_list);
hlist_del(&dev->name_hlist);
hlist_del_rcu(&dev->name_hlist);
hlist_del_rcu(&dev->index_hlist);
write_unlock_bh(&dev_base_lock);
}
Expand Down Expand Up @@ -598,6 +598,32 @@ struct net_device *__dev_get_by_name(struct net *net, const char *name)
}
EXPORT_SYMBOL(__dev_get_by_name);

/**
* dev_get_by_name_rcu - find a device by its name
* @net: the applicable net namespace
* @name: name to find
*
* Find an interface by name.
* If the name is found a pointer to the device is returned.
* If the name is not found then %NULL is returned.
* The reference counters are not incremented so the caller must be
* careful with locks. The caller must hold RCU lock.
*/

struct net_device *dev_get_by_name_rcu(struct net *net, const char *name)
{
struct hlist_node *p;
struct net_device *dev;
struct hlist_head *head = dev_name_hash(net, name);

hlist_for_each_entry_rcu(dev, p, head, name_hlist)
if (!strncmp(dev->name, name, IFNAMSIZ))
return dev;

return NULL;
}
EXPORT_SYMBOL(dev_get_by_name_rcu);

/**
* dev_get_by_name - find a device by its name
* @net: the applicable net namespace
Expand All @@ -614,11 +640,11 @@ struct net_device *dev_get_by_name(struct net *net, const char *name)
{
struct net_device *dev;

read_lock(&dev_base_lock);
dev = __dev_get_by_name(net, name);
rcu_read_lock();
dev = dev_get_by_name_rcu(net, name);
if (dev)
dev_hold(dev);
read_unlock(&dev_base_lock);
rcu_read_unlock();
return dev;
}
EXPORT_SYMBOL(dev_get_by_name);
Expand Down Expand Up @@ -960,7 +986,12 @@ int dev_change_name(struct net_device *dev, const char *newname)

write_lock_bh(&dev_base_lock);
hlist_del(&dev->name_hlist);
hlist_add_head(&dev->name_hlist, dev_name_hash(net, dev->name));
write_unlock_bh(&dev_base_lock);

synchronize_rcu();

write_lock_bh(&dev_base_lock);
hlist_add_head_rcu(&dev->name_hlist, dev_name_hash(net, dev->name));
write_unlock_bh(&dev_base_lock);

ret = call_netdevice_notifiers(NETDEV_CHANGENAME, dev);
Expand Down Expand Up @@ -1062,9 +1093,9 @@ void dev_load(struct net *net, const char *name)
{
struct net_device *dev;

read_lock(&dev_base_lock);
dev = __dev_get_by_name(net, name);
read_unlock(&dev_base_lock);
rcu_read_lock();
dev = dev_get_by_name_rcu(net, name);
rcu_read_unlock();

if (!dev && capable(CAP_NET_ADMIN))
request_module("%s", name);
Expand Down

0 comments on commit 1c6768b

Please sign in to comment.