diff options
author | nikolay@redhat.com <nikolay@redhat.com> | 2013-04-22 04:12:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-25 04:03:21 -0400 |
commit | c6cdcf6d82bc8f53e64ad59464e0114fe48e28bb (patch) | |
tree | 3a15cd4d3dcbb1d057d7e60fe1efb1346c0ef942 | |
parent | ecf01c22be034690b621d92c9ff488d607a9995a (diff) |
bonding: fix locking in enslave failure path
In commit 3c5913b53fefc9d9e15a2d0f93042766658d9f3f ("bonding:
primary_slave & curr_active_slave are not cleaned on enslave failure")
I didn't account for the use of curr_active_slave without curr_slave_lock
and since there are such users, we should hold bond->lock for writing while
setting it to NULL (in the NULL case we don't need the curr_slave_lock).
Keeping the bond lock as to avoid the extra release/acquire cycle.
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.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index dbbea0eec134..7db40de1b41f 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1915,14 +1915,16 @@ err_detach: | |||
1915 | bond_detach_slave(bond, new_slave); | 1915 | bond_detach_slave(bond, new_slave); |
1916 | if (bond->primary_slave == new_slave) | 1916 | if (bond->primary_slave == new_slave) |
1917 | bond->primary_slave = NULL; | 1917 | bond->primary_slave = NULL; |
1918 | write_unlock_bh(&bond->lock); | ||
1919 | if (bond->curr_active_slave == new_slave) { | 1918 | if (bond->curr_active_slave == new_slave) { |
1919 | bond_change_active_slave(bond, NULL); | ||
1920 | write_unlock_bh(&bond->lock); | ||
1920 | read_lock(&bond->lock); | 1921 | read_lock(&bond->lock); |
1921 | write_lock_bh(&bond->curr_slave_lock); | 1922 | write_lock_bh(&bond->curr_slave_lock); |
1922 | bond_change_active_slave(bond, NULL); | ||
1923 | bond_select_active_slave(bond); | 1923 | bond_select_active_slave(bond); |
1924 | write_unlock_bh(&bond->curr_slave_lock); | 1924 | write_unlock_bh(&bond->curr_slave_lock); |
1925 | read_unlock(&bond->lock); | 1925 | read_unlock(&bond->lock); |
1926 | } else { | ||
1927 | write_unlock_bh(&bond->lock); | ||
1926 | } | 1928 | } |
1927 | slave_disable_netpoll(new_slave); | 1929 | slave_disable_netpoll(new_slave); |
1928 | 1930 | ||