diff options
author | Veaceslav Falico <vfalico@redhat.com> | 2014-01-14 20:58:51 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2014-04-18 03:49:17 (GMT) |
commit | 45ce45c69750b93b8262aa66792185bd49150293 (patch) | |
tree | 8aa045c58b691644d979baebefefa62094d9e8bf | |
parent | 0be682ca768d671c91cfd1379759efcb3b29102a (diff) | |
download | linux-fsl-qoriq-45ce45c69750b93b8262aa66792185bd49150293.tar.xz |
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>
(cherry picked and merged from commit 5bb025fae53889cc99a21058c5dd369bf8cce820)
Change-Id: I31a2f1800a7a181189c031d53ea1deef0ae137fc
Reviewed-on: http://git.am.freescale.net:8181/11048
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Mihai Claudiu Caraman <mihai.caraman@freescale.com>
Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
-rw-r--r-- | include/linux/netdevice.h | 1 | ||||
-rw-r--r-- | net/core/dev.c | 22 |
2 files changed, 23 insertions, 0 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 8fa1219..cfde9a5 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2886,6 +2886,7 @@ void netdev_upper_dev_unlink(struct net_device *dev, struct net_device *upper_dev); void *netdev_lower_dev_get_private_rcu(struct net_device *dev, struct net_device *lower_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); diff --git a/net/core/dev.c b/net/core/dev.c index d518938..df70378 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1118,6 +1118,8 @@ rollback: 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); @@ -1137,6 +1139,7 @@ rollback: 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", @@ -4999,6 +5002,25 @@ void *netdev_lower_dev_get_private_rcu(struct net_device *dev, } EXPORT_SYMBOL(netdev_lower_dev_get_private_rcu); +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) { |