Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89fc8632 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'netdev_sysfs_symlink_rename'



Veaceslav Falico says:

====================
net: rename device's sysfs symlinks on name change

First patch only adds helper functions and cleans up the code a bit, second
one already does the renaming.

v1->v2:
Don't export the function, as it's used only in dev.c.
====================

Reported-by: default avatarDing Tianhong <dingtianhong@huawei.com>
CC: Ding Tianhong <dingtianhong@huawei.com>
CC: "David S. Miller" <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Nicolas Dichtel <nicolas.dichtel@6wind.com>
CC: Cong Wang <amwang@redhat.com>
CC: netdev@vger.kernel.org
Signed-off-by: default avatarVeaceslav Falico <vfalico@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b9381985 5bb025fa
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2941,6 +2941,7 @@ int netdev_master_upper_dev_link_private(struct net_device *dev,
					 void *private);
void netdev_upper_dev_unlink(struct net_device *dev,
			     struct net_device *upper_dev);
void netdev_adjacent_rename_links(struct net_device *dev, char *oldname);
void *netdev_lower_dev_get_private(struct net_device *dev,
				   struct net_device *lower_dev);
int skb_checksum_help(struct sk_buff *skb);
+52 −27
Original line number Diff line number Diff line
@@ -1119,6 +1119,8 @@ int dev_change_name(struct net_device *dev, const char *newname)

	write_seqcount_end(&devnet_rename_seq);

	netdev_adjacent_rename_links(dev, oldname);

	write_lock_bh(&dev_base_lock);
	hlist_del_rcu(&dev->name_hlist);
	write_unlock_bh(&dev_base_lock);
@@ -1138,6 +1140,7 @@ int dev_change_name(struct net_device *dev, const char *newname)
			err = ret;
			write_seqcount_begin(&devnet_rename_seq);
			memcpy(dev->name, oldname, IFNAMSIZ);
			memcpy(oldname, newname, IFNAMSIZ);
			goto rollback;
		} else {
			pr_err("%s: name change rollback failed: %d\n",
@@ -4623,13 +4626,36 @@ struct net_device *netdev_master_upper_dev_get_rcu(struct net_device *dev)
}
EXPORT_SYMBOL(netdev_master_upper_dev_get_rcu);

int netdev_adjacent_sysfs_add(struct net_device *dev,
			      struct net_device *adj_dev,
			      struct list_head *dev_list)
{
	char linkname[IFNAMSIZ+7];
	sprintf(linkname, dev_list == &dev->adj_list.upper ?
		"upper_%s" : "lower_%s", adj_dev->name);
	return sysfs_create_link(&(dev->dev.kobj), &(adj_dev->dev.kobj),
				 linkname);
}
void netdev_adjacent_sysfs_del(struct net_device *dev,
			       char *name,
			       struct list_head *dev_list)
{
	char linkname[IFNAMSIZ+7];
	sprintf(linkname, dev_list == &dev->adj_list.upper ?
		"upper_%s" : "lower_%s", name);
	sysfs_remove_link(&(dev->dev.kobj), linkname);
}

#define netdev_adjacent_is_neigh_list(dev, dev_list) \
		(dev_list == &dev->adj_list.upper || \
		 dev_list == &dev->adj_list.lower)

static int __netdev_adjacent_dev_insert(struct net_device *dev,
					struct net_device *adj_dev,
					struct list_head *dev_list,
					void *private, bool master)
{
	struct netdev_adjacent *adj;
	char linkname[IFNAMSIZ+7];
	int ret;

	adj = __netdev_find_adj(dev, adj_dev, dev_list);
@@ -4652,16 +4678,8 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,
	pr_debug("dev_hold for %s, because of link added from %s to %s\n",
		 adj_dev->name, dev->name, adj_dev->name);

	if (dev_list == &dev->adj_list.lower) {
		sprintf(linkname, "lower_%s", adj_dev->name);
		ret = sysfs_create_link(&(dev->dev.kobj),
					&(adj_dev->dev.kobj), linkname);
		if (ret)
			goto free_adj;
	} else if (dev_list == &dev->adj_list.upper) {
		sprintf(linkname, "upper_%s", adj_dev->name);
		ret = sysfs_create_link(&(dev->dev.kobj),
					&(adj_dev->dev.kobj), linkname);
	if (netdev_adjacent_is_neigh_list(dev, dev_list)) {
		ret = netdev_adjacent_sysfs_add(dev, adj_dev, dev_list);
		if (ret)
			goto free_adj;
	}
@@ -4681,14 +4699,8 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,
	return 0;

remove_symlinks:
	if (dev_list == &dev->adj_list.lower) {
		sprintf(linkname, "lower_%s", adj_dev->name);
		sysfs_remove_link(&(dev->dev.kobj), linkname);
	} else if (dev_list == &dev->adj_list.upper) {
		sprintf(linkname, "upper_%s", adj_dev->name);
		sysfs_remove_link(&(dev->dev.kobj), linkname);
	}

	if (netdev_adjacent_is_neigh_list(dev, dev_list))
		netdev_adjacent_sysfs_del(dev, adj_dev->name, dev_list);
free_adj:
	kfree(adj);
	dev_put(adj_dev);
@@ -4701,7 +4713,6 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev,
					 struct list_head *dev_list)
{
	struct netdev_adjacent *adj;
	char linkname[IFNAMSIZ+7];

	adj = __netdev_find_adj(dev, adj_dev, dev_list);

@@ -4721,13 +4732,8 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev,
	if (adj->master)
		sysfs_remove_link(&(dev->dev.kobj), "master");

	if (dev_list == &dev->adj_list.lower) {
		sprintf(linkname, "lower_%s", adj_dev->name);
		sysfs_remove_link(&(dev->dev.kobj), linkname);
	} else if (dev_list == &dev->adj_list.upper) {
		sprintf(linkname, "upper_%s", adj_dev->name);
		sysfs_remove_link(&(dev->dev.kobj), linkname);
	}
	if (netdev_adjacent_is_neigh_list(dev, dev_list))
		netdev_adjacent_sysfs_del(dev, adj_dev->name, dev_list);

	list_del_rcu(&adj->list);
	pr_debug("dev_put for %s, because link removed from %s to %s\n",
@@ -4996,6 +5002,25 @@ void netdev_upper_dev_unlink(struct net_device *dev,
}
EXPORT_SYMBOL(netdev_upper_dev_unlink);

void netdev_adjacent_rename_links(struct net_device *dev, char *oldname)
{
	struct netdev_adjacent *iter;

	list_for_each_entry(iter, &dev->adj_list.upper, list) {
		netdev_adjacent_sysfs_del(iter->dev, oldname,
					  &iter->dev->adj_list.lower);
		netdev_adjacent_sysfs_add(iter->dev, dev,
					  &iter->dev->adj_list.lower);
	}

	list_for_each_entry(iter, &dev->adj_list.lower, list) {
		netdev_adjacent_sysfs_del(iter->dev, oldname,
					  &iter->dev->adj_list.upper);
		netdev_adjacent_sysfs_add(iter->dev, dev,
					  &iter->dev->adj_list.upper);
	}
}

void *netdev_lower_dev_get_private(struct net_device *dev,
				   struct net_device *lower_dev)
{