diff options
author | Veaceslav Falico <vfalico@redhat.com> | 2014-01-14 15:58:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-15 18:16:20 -0500 |
commit | 5bb025fae53889cc99a21058c5dd369bf8cce820 (patch) | |
tree | cc80601cdb7096b9dc4d9d5f14eb477c4dd82322 /net/core | |
parent | 3ee32707560955e92d30f7f6e5138cb92a3b1a7e (diff) |
net: rename sysfs symlinks on device name change
Currently, we don't rename the upper/lower_ifc symlinks in
/sys/class/net/*/ , which might result stale/duplicate links/names.
Fix this by adding netdev_adjacent_rename_links(dev, oldname) which renames
all the upper/lower interface's links to dev from the upper/lower_oldname
to the new name.
We don't need a rollback because only we control these symlinks and if we
fail to rename them - sysfs will anyway complain.
Reported-by: Ding 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>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 130d3bd0ce6f..995755733997 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1119,6 +1119,8 @@ rollback: | |||
1119 | 1119 | ||
1120 | write_seqcount_end(&devnet_rename_seq); | 1120 | write_seqcount_end(&devnet_rename_seq); |
1121 | 1121 | ||
1122 | netdev_adjacent_rename_links(dev, oldname); | ||
1123 | |||
1122 | write_lock_bh(&dev_base_lock); | 1124 | write_lock_bh(&dev_base_lock); |
1123 | hlist_del_rcu(&dev->name_hlist); | 1125 | hlist_del_rcu(&dev->name_hlist); |
1124 | write_unlock_bh(&dev_base_lock); | 1126 | write_unlock_bh(&dev_base_lock); |
@@ -1138,6 +1140,7 @@ rollback: | |||
1138 | err = ret; | 1140 | err = ret; |
1139 | write_seqcount_begin(&devnet_rename_seq); | 1141 | write_seqcount_begin(&devnet_rename_seq); |
1140 | memcpy(dev->name, oldname, IFNAMSIZ); | 1142 | memcpy(dev->name, oldname, IFNAMSIZ); |
1143 | memcpy(oldname, newname, IFNAMSIZ); | ||
1141 | goto rollback; | 1144 | goto rollback; |
1142 | } else { | 1145 | } else { |
1143 | pr_err("%s: name change rollback failed: %d\n", | 1146 | pr_err("%s: name change rollback failed: %d\n", |
@@ -4999,6 +5002,25 @@ void netdev_upper_dev_unlink(struct net_device *dev, | |||
4999 | } | 5002 | } |
5000 | EXPORT_SYMBOL(netdev_upper_dev_unlink); | 5003 | EXPORT_SYMBOL(netdev_upper_dev_unlink); |
5001 | 5004 | ||
5005 | void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) | ||
5006 | { | ||
5007 | struct netdev_adjacent *iter; | ||
5008 | |||
5009 | list_for_each_entry(iter, &dev->adj_list.upper, list) { | ||
5010 | netdev_adjacent_sysfs_del(iter->dev, oldname, | ||
5011 | &iter->dev->adj_list.lower); | ||
5012 | netdev_adjacent_sysfs_add(iter->dev, dev, | ||
5013 | &iter->dev->adj_list.lower); | ||
5014 | } | ||
5015 | |||
5016 | list_for_each_entry(iter, &dev->adj_list.lower, list) { | ||
5017 | netdev_adjacent_sysfs_del(iter->dev, oldname, | ||
5018 | &iter->dev->adj_list.upper); | ||
5019 | netdev_adjacent_sysfs_add(iter->dev, dev, | ||
5020 | &iter->dev->adj_list.upper); | ||
5021 | } | ||
5022 | } | ||
5023 | |||
5002 | void *netdev_lower_dev_get_private(struct net_device *dev, | 5024 | void *netdev_lower_dev_get_private(struct net_device *dev, |
5003 | struct net_device *lower_dev) | 5025 | struct net_device *lower_dev) |
5004 | { | 5026 | { |