aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2009-06-12 15:02:47 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-14 02:28:56 -0400
commit9e71626c1c23ec69372c43c6fe66c1171032bf42 (patch)
tree664e2c6d342c210a6f041b97ed9a3d9c1bc58f06 /drivers/net/bonding
parent7e0838404541d2758bee089632690aabd82f3d5d (diff)
bonding: fix destructor
It is not safe to use a network device destructor that is a function in the module, since it can be called after module is unloaded if sysfs handle is open. When eventually using netlink, the device cleanup code needs to be done via uninit function. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_main.c21
-rw-r--r--drivers/net/bonding/bond_sysfs.c2
-rw-r--r--drivers/net/bonding/bonding.h1
3 files changed, 9 insertions, 15 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 23b832ffe7a..2fc3561e099 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1972,25 +1972,19 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1972* Destroy a bonding device. 1972* Destroy a bonding device.
1973* Must be under rtnl_lock when this function is called. 1973* Must be under rtnl_lock when this function is called.
1974*/ 1974*/
1975void bond_destroy(struct bonding *bond) 1975static void bond_uninit(struct net_device *bond_dev)
1976{
1977 bond_deinit(bond->dev);
1978 bond_destroy_sysfs_entry(bond);
1979 unregister_netdevice(bond->dev);
1980}
1981
1982static void bond_destructor(struct net_device *bond_dev)
1983{ 1976{
1984 struct bonding *bond = netdev_priv(bond_dev); 1977 struct bonding *bond = netdev_priv(bond_dev);
1985 1978
1979 bond_deinit(bond_dev);
1980 bond_destroy_sysfs_entry(bond);
1981
1986 if (bond->wq) 1982 if (bond->wq)
1987 destroy_workqueue(bond->wq); 1983 destroy_workqueue(bond->wq);
1988 1984
1989 netif_addr_lock_bh(bond_dev); 1985 netif_addr_lock_bh(bond_dev);
1990 bond_mc_list_destroy(bond); 1986 bond_mc_list_destroy(bond);
1991 netif_addr_unlock_bh(bond_dev); 1987 netif_addr_unlock_bh(bond_dev);
1992
1993 free_netdev(bond_dev);
1994} 1988}
1995 1989
1996/* 1990/*
@@ -2006,7 +2000,7 @@ int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *sl
2006 if ((ret == 0) && (bond->slave_cnt == 0)) { 2000 if ((ret == 0) && (bond->slave_cnt == 0)) {
2007 printk(KERN_INFO DRV_NAME ": %s: destroying bond %s.\n", 2001 printk(KERN_INFO DRV_NAME ": %s: destroying bond %s.\n",
2008 bond_dev->name, bond_dev->name); 2002 bond_dev->name, bond_dev->name);
2009 bond_destroy(bond); 2003 unregister_netdevice(bond_dev);
2010 } 2004 }
2011 return ret; 2005 return ret;
2012} 2006}
@@ -4572,6 +4566,7 @@ static const struct ethtool_ops bond_ethtool_ops = {
4572}; 4566};
4573 4567
4574static const struct net_device_ops bond_netdev_ops = { 4568static const struct net_device_ops bond_netdev_ops = {
4569 .ndo_uninit = bond_uninit,
4575 .ndo_open = bond_open, 4570 .ndo_open = bond_open,
4576 .ndo_stop = bond_close, 4571 .ndo_stop = bond_close,
4577 .ndo_start_xmit = bond_start_xmit, 4572 .ndo_start_xmit = bond_start_xmit,
@@ -4622,7 +4617,7 @@ static int bond_init(struct net_device *bond_dev)
4622 bond_dev->ethtool_ops = &bond_ethtool_ops; 4617 bond_dev->ethtool_ops = &bond_ethtool_ops;
4623 bond_set_mode_ops(bond, bond->params.mode); 4618 bond_set_mode_ops(bond, bond->params.mode);
4624 4619
4625 bond_dev->destructor = bond_destructor; 4620 bond_dev->destructor = free_netdev;
4626 4621
4627 /* Initialize the device options */ 4622 /* Initialize the device options */
4628 bond_dev->tx_queue_len = 0; 4623 bond_dev->tx_queue_len = 0;
@@ -4706,7 +4701,7 @@ static void bond_free_all(void)
4706 bond_work_cancel_all(bond); 4701 bond_work_cancel_all(bond);
4707 /* Release the bonded slaves */ 4702 /* Release the bonded slaves */
4708 bond_release_all(bond_dev); 4703 bond_release_all(bond_dev);
4709 bond_destroy(bond); 4704 unregister_netdevice(bond_dev);
4710 } 4705 }
4711 4706
4712 bond_destroy_proc_dir(); 4707 bond_destroy_proc_dir();
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 8041b679353..72357597fa1 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -127,7 +127,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
127 printk(KERN_INFO DRV_NAME 127 printk(KERN_INFO DRV_NAME
128 ": %s is being deleted...\n", 128 ": %s is being deleted...\n",
129 bond->dev->name); 129 bond->dev->name);
130 bond_destroy(bond); 130 unregister_netdevice(bond->dev);
131 goto out_unlock; 131 goto out_unlock;
132 } 132 }
133 133
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index af81e9b7fe3..6290a502742 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -322,7 +322,6 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond)
322struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); 322struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
323int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); 323int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
324int bond_create(const char *name); 324int bond_create(const char *name);
325void bond_destroy(struct bonding *bond);
326int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev); 325int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
327int bond_create_sysfs(void); 326int bond_create_sysfs(void);
328void bond_destroy_sysfs(void); 327void bond_destroy_sysfs(void);