Skip to content

Commit

Permalink
bonding: fix destructor
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Jun 14, 2009
1 parent 7e08384 commit 9e71626
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 15 deletions.
21 changes: 8 additions & 13 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1972,25 +1972,19 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
* Destroy a bonding device.
* Must be under rtnl_lock when this function is called.
*/
void bond_destroy(struct bonding *bond)
{
bond_deinit(bond->dev);
bond_destroy_sysfs_entry(bond);
unregister_netdevice(bond->dev);
}

static void bond_destructor(struct net_device *bond_dev)
static void bond_uninit(struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);

bond_deinit(bond_dev);
bond_destroy_sysfs_entry(bond);

if (bond->wq)
destroy_workqueue(bond->wq);

netif_addr_lock_bh(bond_dev);
bond_mc_list_destroy(bond);
netif_addr_unlock_bh(bond_dev);

free_netdev(bond_dev);
}

/*
Expand All @@ -2006,7 +2000,7 @@ int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *sl
if ((ret == 0) && (bond->slave_cnt == 0)) {
printk(KERN_INFO DRV_NAME ": %s: destroying bond %s.\n",
bond_dev->name, bond_dev->name);
bond_destroy(bond);
unregister_netdevice(bond_dev);
}
return ret;
}
Expand Down Expand Up @@ -4572,6 +4566,7 @@ static const struct ethtool_ops bond_ethtool_ops = {
};

static const struct net_device_ops bond_netdev_ops = {
.ndo_uninit = bond_uninit,
.ndo_open = bond_open,
.ndo_stop = bond_close,
.ndo_start_xmit = bond_start_xmit,
Expand Down Expand Up @@ -4622,7 +4617,7 @@ static int bond_init(struct net_device *bond_dev)
bond_dev->ethtool_ops = &bond_ethtool_ops;
bond_set_mode_ops(bond, bond->params.mode);

bond_dev->destructor = bond_destructor;
bond_dev->destructor = free_netdev;

/* Initialize the device options */
bond_dev->tx_queue_len = 0;
Expand Down Expand Up @@ -4706,7 +4701,7 @@ static void bond_free_all(void)
bond_work_cancel_all(bond);
/* Release the bonded slaves */
bond_release_all(bond_dev);
bond_destroy(bond);
unregister_netdevice(bond_dev);
}

bond_destroy_proc_dir();
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/bonding/bond_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
printk(KERN_INFO DRV_NAME
": %s is being deleted...\n",
bond->dev->name);
bond_destroy(bond);
unregister_netdevice(bond->dev);
goto out_unlock;
}

Expand Down
1 change: 0 additions & 1 deletion drivers/net/bonding/bonding.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond)
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
int bond_create(const char *name);
void bond_destroy(struct bonding *bond);
int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
int bond_create_sysfs(void);
void bond_destroy_sysfs(void);
Expand Down

0 comments on commit 9e71626

Please sign in to comment.