diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 93 |
1 files changed, 75 insertions, 18 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index ee4035571c21..6cc8a70350ac 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -817,7 +817,9 @@ int dev_alloc_name(struct net_device *dev, const char *name) | |||
817 | */ | 817 | */ |
818 | int dev_change_name(struct net_device *dev, char *newname) | 818 | int dev_change_name(struct net_device *dev, char *newname) |
819 | { | 819 | { |
820 | char oldname[IFNAMSIZ]; | ||
820 | int err = 0; | 821 | int err = 0; |
822 | int ret; | ||
821 | 823 | ||
822 | ASSERT_RTNL(); | 824 | ASSERT_RTNL(); |
823 | 825 | ||
@@ -827,6 +829,8 @@ int dev_change_name(struct net_device *dev, char *newname) | |||
827 | if (!dev_valid_name(newname)) | 829 | if (!dev_valid_name(newname)) |
828 | return -EINVAL; | 830 | return -EINVAL; |
829 | 831 | ||
832 | memcpy(oldname, dev->name, IFNAMSIZ); | ||
833 | |||
830 | if (strchr(newname, '%')) { | 834 | if (strchr(newname, '%')) { |
831 | err = dev_alloc_name(dev, newname); | 835 | err = dev_alloc_name(dev, newname); |
832 | if (err < 0) | 836 | if (err < 0) |
@@ -838,10 +842,28 @@ int dev_change_name(struct net_device *dev, char *newname) | |||
838 | else | 842 | else |
839 | strlcpy(dev->name, newname, IFNAMSIZ); | 843 | strlcpy(dev->name, newname, IFNAMSIZ); |
840 | 844 | ||
845 | rollback: | ||
841 | device_rename(&dev->dev, dev->name); | 846 | device_rename(&dev->dev, dev->name); |
847 | |||
848 | write_lock_bh(&dev_base_lock); | ||
842 | hlist_del(&dev->name_hlist); | 849 | hlist_del(&dev->name_hlist); |
843 | hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); | 850 | hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); |
844 | raw_notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); | 851 | write_unlock_bh(&dev_base_lock); |
852 | |||
853 | ret = raw_notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); | ||
854 | ret = notifier_to_errno(ret); | ||
855 | |||
856 | if (ret) { | ||
857 | if (err) { | ||
858 | printk(KERN_ERR | ||
859 | "%s: name change rollback failed: %d.\n", | ||
860 | dev->name, ret); | ||
861 | } else { | ||
862 | err = ret; | ||
863 | memcpy(dev->name, oldname, IFNAMSIZ); | ||
864 | goto rollback; | ||
865 | } | ||
866 | } | ||
845 | 867 | ||
846 | return err; | 868 | return err; |
847 | } | 869 | } |
@@ -1054,20 +1076,43 @@ int dev_close(struct net_device *dev) | |||
1054 | int register_netdevice_notifier(struct notifier_block *nb) | 1076 | int register_netdevice_notifier(struct notifier_block *nb) |
1055 | { | 1077 | { |
1056 | struct net_device *dev; | 1078 | struct net_device *dev; |
1079 | struct net_device *last; | ||
1057 | int err; | 1080 | int err; |
1058 | 1081 | ||
1059 | rtnl_lock(); | 1082 | rtnl_lock(); |
1060 | err = raw_notifier_chain_register(&netdev_chain, nb); | 1083 | err = raw_notifier_chain_register(&netdev_chain, nb); |
1061 | if (!err) { | 1084 | if (err) |
1062 | for_each_netdev(dev) { | 1085 | goto unlock; |
1063 | nb->notifier_call(nb, NETDEV_REGISTER, dev); | ||
1064 | 1086 | ||
1065 | if (dev->flags & IFF_UP) | 1087 | for_each_netdev(dev) { |
1066 | nb->notifier_call(nb, NETDEV_UP, dev); | 1088 | err = nb->notifier_call(nb, NETDEV_REGISTER, dev); |
1067 | } | 1089 | err = notifier_to_errno(err); |
1090 | if (err) | ||
1091 | goto rollback; | ||
1092 | |||
1093 | if (!(dev->flags & IFF_UP)) | ||
1094 | continue; | ||
1095 | |||
1096 | nb->notifier_call(nb, NETDEV_UP, dev); | ||
1068 | } | 1097 | } |
1098 | |||
1099 | unlock: | ||
1069 | rtnl_unlock(); | 1100 | rtnl_unlock(); |
1070 | return err; | 1101 | return err; |
1102 | |||
1103 | rollback: | ||
1104 | last = dev; | ||
1105 | for_each_netdev(dev) { | ||
1106 | if (dev == last) | ||
1107 | break; | ||
1108 | |||
1109 | if (dev->flags & IFF_UP) { | ||
1110 | nb->notifier_call(nb, NETDEV_GOING_DOWN, dev); | ||
1111 | nb->notifier_call(nb, NETDEV_DOWN, dev); | ||
1112 | } | ||
1113 | nb->notifier_call(nb, NETDEV_UNREGISTER, dev); | ||
1114 | } | ||
1115 | goto unlock; | ||
1071 | } | 1116 | } |
1072 | 1117 | ||
1073 | /** | 1118 | /** |
@@ -2718,9 +2763,11 @@ int __dev_addr_add(struct dev_addr_list **list, int *count, | |||
2718 | /** | 2763 | /** |
2719 | * dev_unicast_delete - Release secondary unicast address. | 2764 | * dev_unicast_delete - Release secondary unicast address. |
2720 | * @dev: device | 2765 | * @dev: device |
2766 | * @addr: address to delete | ||
2767 | * @alen: length of @addr | ||
2721 | * | 2768 | * |
2722 | * Release reference to a secondary unicast address and remove it | 2769 | * Release reference to a secondary unicast address and remove it |
2723 | * from the device if the reference count drop to zero. | 2770 | * from the device if the reference count drops to zero. |
2724 | * | 2771 | * |
2725 | * The caller must hold the rtnl_mutex. | 2772 | * The caller must hold the rtnl_mutex. |
2726 | */ | 2773 | */ |
@@ -2742,6 +2789,8 @@ EXPORT_SYMBOL(dev_unicast_delete); | |||
2742 | /** | 2789 | /** |
2743 | * dev_unicast_add - add a secondary unicast address | 2790 | * dev_unicast_add - add a secondary unicast address |
2744 | * @dev: device | 2791 | * @dev: device |
2792 | * @addr: address to delete | ||
2793 | * @alen: length of @addr | ||
2745 | * | 2794 | * |
2746 | * Add a secondary unicast address to the device or increase | 2795 | * Add a secondary unicast address to the device or increase |
2747 | * the reference count if it already exists. | 2796 | * the reference count if it already exists. |
@@ -3333,7 +3382,7 @@ int register_netdevice(struct net_device *dev) | |||
3333 | 3382 | ||
3334 | if (!dev_valid_name(dev->name)) { | 3383 | if (!dev_valid_name(dev->name)) { |
3335 | ret = -EINVAL; | 3384 | ret = -EINVAL; |
3336 | goto out; | 3385 | goto err_uninit; |
3337 | } | 3386 | } |
3338 | 3387 | ||
3339 | dev->ifindex = dev_new_index(); | 3388 | dev->ifindex = dev_new_index(); |
@@ -3347,7 +3396,7 @@ int register_netdevice(struct net_device *dev) | |||
3347 | = hlist_entry(p, struct net_device, name_hlist); | 3396 | = hlist_entry(p, struct net_device, name_hlist); |
3348 | if (!strncmp(d->name, dev->name, IFNAMSIZ)) { | 3397 | if (!strncmp(d->name, dev->name, IFNAMSIZ)) { |
3349 | ret = -EEXIST; | 3398 | ret = -EEXIST; |
3350 | goto out; | 3399 | goto err_uninit; |
3351 | } | 3400 | } |
3352 | } | 3401 | } |
3353 | 3402 | ||
@@ -3407,7 +3456,7 @@ int register_netdevice(struct net_device *dev) | |||
3407 | 3456 | ||
3408 | ret = netdev_register_sysfs(dev); | 3457 | ret = netdev_register_sysfs(dev); |
3409 | if (ret) | 3458 | if (ret) |
3410 | goto out; | 3459 | goto err_uninit; |
3411 | dev->reg_state = NETREG_REGISTERED; | 3460 | dev->reg_state = NETREG_REGISTERED; |
3412 | 3461 | ||
3413 | /* | 3462 | /* |
@@ -3426,12 +3475,18 @@ int register_netdevice(struct net_device *dev) | |||
3426 | write_unlock_bh(&dev_base_lock); | 3475 | write_unlock_bh(&dev_base_lock); |
3427 | 3476 | ||
3428 | /* Notify protocols, that a new device appeared. */ | 3477 | /* Notify protocols, that a new device appeared. */ |
3429 | raw_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); | 3478 | ret = raw_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); |
3430 | 3479 | ret = notifier_to_errno(ret); | |
3431 | ret = 0; | 3480 | if (ret) |
3481 | unregister_netdevice(dev); | ||
3432 | 3482 | ||
3433 | out: | 3483 | out: |
3434 | return ret; | 3484 | return ret; |
3485 | |||
3486 | err_uninit: | ||
3487 | if (dev->uninit) | ||
3488 | dev->uninit(dev); | ||
3489 | goto out; | ||
3435 | } | 3490 | } |
3436 | 3491 | ||
3437 | /** | 3492 | /** |
@@ -3830,9 +3885,11 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
3830 | 3885 | ||
3831 | #ifdef CONFIG_NET_DMA | 3886 | #ifdef CONFIG_NET_DMA |
3832 | /** | 3887 | /** |
3833 | * net_dma_rebalance - | 3888 | * net_dma_rebalance - try to maintain one DMA channel per CPU |
3834 | * This is called when the number of channels allocated to the net_dma_client | 3889 | * @net_dma: DMA client and associated data (lock, channels, channel_mask) |
3835 | * changes. The net_dma_client tries to have one DMA channel per CPU. | 3890 | * |
3891 | * This is called when the number of channels allocated to the net_dma client | ||
3892 | * changes. The net_dma client tries to have one DMA channel per CPU. | ||
3836 | */ | 3893 | */ |
3837 | 3894 | ||
3838 | static void net_dma_rebalance(struct net_dma *net_dma) | 3895 | static void net_dma_rebalance(struct net_dma *net_dma) |
@@ -3869,7 +3926,7 @@ static void net_dma_rebalance(struct net_dma *net_dma) | |||
3869 | * netdev_dma_event - event callback for the net_dma_client | 3926 | * netdev_dma_event - event callback for the net_dma_client |
3870 | * @client: should always be net_dma_client | 3927 | * @client: should always be net_dma_client |
3871 | * @chan: DMA channel for the event | 3928 | * @chan: DMA channel for the event |
3872 | * @event: event type | 3929 | * @state: DMA state to be handled |
3873 | */ | 3930 | */ |
3874 | static enum dma_state_client | 3931 | static enum dma_state_client |
3875 | netdev_dma_event(struct dma_client *client, struct dma_chan *chan, | 3932 | netdev_dma_event(struct dma_client *client, struct dma_chan *chan, |