summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornikolay@redhat.com <nikolay@redhat.com>2013-04-18 07:33:36 +0000
committerDavid S. Miller <davem@davemloft.net>2013-04-19 17:48:19 -0400
commit3c5913b53fefc9d9e15a2d0f93042766658d9f3f (patch)
tree772296984f4e7f56b8cc0aa4949cfee3582ddc8b
parenta506e7b479e1215c230e4b87fedc246cf748537f (diff)
downloadlinux-3c5913b53fefc9d9e15a2d0f93042766658d9f3f.tar.bz2
bonding: primary_slave & curr_active_slave are not cleaned on enslave failure
On enslave failure primary_slave can point to new_slave which is to be freed, and the same applies to curr_active_slave. So check if this is the case and clean up properly after err_detach because that's the first error code path after they're set. Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bonding/bond_main.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index dd67c49070d7..1137d5eac450 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1909,7 +1909,17 @@ err_detach:
bond_del_vlans_from_slave(bond, slave_dev);
write_lock_bh(&bond->lock);
bond_detach_slave(bond, new_slave);
+ if (bond->primary_slave == new_slave)
+ bond->primary_slave = NULL;
write_unlock_bh(&bond->lock);
+ if (bond->curr_active_slave == new_slave) {
+ read_lock(&bond->lock);
+ write_lock_bh(&bond->curr_slave_lock);
+ bond_change_active_slave(bond, NULL);
+ bond_select_active_slave(bond);
+ write_unlock_bh(&bond->curr_slave_lock);
+ read_unlock(&bond->lock);
+ }
err_close:
slave_dev->priv_flags &= ~IFF_BONDING;