diff options
author | Jay Vosburgh <fubar@us.ibm.com> | 2008-01-17 19:24:57 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-18 14:38:38 -0500 |
commit | e934dd7862e7f613b2ce9730d548a0a70913c8f7 (patch) | |
tree | 9f6cd6b7e15614bc47d85806e4b5472ac65ab2ca /drivers/net | |
parent | 03bbe082cffc4533f6557bf23f0c672307067246 (diff) |
bonding: fix locking in sysfs primary/active selection
Fix the functions that store the primary and active slave
options via sysfs to hold the correct locks in the correct order.
The bond_change_active_slave and bond_select_active_slave
functions both require rtnl, bond->lock for read and curr_slave_lock for
write_bh, and no other locks. This is so that the lower level
mode-specific functions (notably for balance-alb mode) can release locks
down to just rtnl in order to call, e.g., dev_set_mac_address with the
locks it expects (rtnl only).
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 11b76b35241..28a2d803e7e 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -1075,7 +1075,10 @@ static ssize_t bonding_store_primary(struct device *d, | |||
1075 | struct slave *slave; | 1075 | struct slave *slave; |
1076 | struct bonding *bond = to_bond(d); | 1076 | struct bonding *bond = to_bond(d); |
1077 | 1077 | ||
1078 | write_lock_bh(&bond->lock); | 1078 | rtnl_lock(); |
1079 | read_lock(&bond->lock); | ||
1080 | write_lock_bh(&bond->curr_slave_lock); | ||
1081 | |||
1079 | if (!USES_PRIMARY(bond->params.mode)) { | 1082 | if (!USES_PRIMARY(bond->params.mode)) { |
1080 | printk(KERN_INFO DRV_NAME | 1083 | printk(KERN_INFO DRV_NAME |
1081 | ": %s: Unable to set primary slave; %s is in mode %d\n", | 1084 | ": %s: Unable to set primary slave; %s is in mode %d\n", |
@@ -1109,8 +1112,8 @@ static ssize_t bonding_store_primary(struct device *d, | |||
1109 | } | 1112 | } |
1110 | } | 1113 | } |
1111 | out: | 1114 | out: |
1112 | write_unlock_bh(&bond->lock); | 1115 | write_unlock_bh(&bond->curr_slave_lock); |
1113 | 1116 | read_unlock(&bond->lock); | |
1114 | rtnl_unlock(); | 1117 | rtnl_unlock(); |
1115 | 1118 | ||
1116 | return count; | 1119 | return count; |
@@ -1190,7 +1193,8 @@ static ssize_t bonding_store_active_slave(struct device *d, | |||
1190 | struct bonding *bond = to_bond(d); | 1193 | struct bonding *bond = to_bond(d); |
1191 | 1194 | ||
1192 | rtnl_lock(); | 1195 | rtnl_lock(); |
1193 | write_lock_bh(&bond->lock); | 1196 | read_lock(&bond->lock); |
1197 | write_lock_bh(&bond->curr_slave_lock); | ||
1194 | 1198 | ||
1195 | if (!USES_PRIMARY(bond->params.mode)) { | 1199 | if (!USES_PRIMARY(bond->params.mode)) { |
1196 | printk(KERN_INFO DRV_NAME | 1200 | printk(KERN_INFO DRV_NAME |
@@ -1247,7 +1251,8 @@ static ssize_t bonding_store_active_slave(struct device *d, | |||
1247 | } | 1251 | } |
1248 | } | 1252 | } |
1249 | out: | 1253 | out: |
1250 | write_unlock_bh(&bond->lock); | 1254 | write_unlock_bh(&bond->curr_slave_lock); |
1255 | read_unlock(&bond->lock); | ||
1251 | rtnl_unlock(); | 1256 | rtnl_unlock(); |
1252 | 1257 | ||
1253 | return count; | 1258 | return count; |