diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2009-05-13 13:02:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-05-19 01:16:00 -0400 |
commit | 496a60cdcd5d0d884dddf6c3b4ea912923a70f13 (patch) | |
tree | dd7c3e4e61d4c4bead3c7bd3db17401431e6d87e /drivers/net/bonding | |
parent | 26574401fef6766f6c3ca25b5c13febe662d2a32 (diff) |
net: FIX bonding sysfs rtnl_lock deadlock
Sysfs files for a network device can not unconditionally take the
rtnl_lock as the bonding sysfs files do. If someone accesses those
sysfs files while the network device is being unregistered with the
rtnl_lock held we will deadlock.
So use trylock and restart_syscall to avoid this problem.
Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index d2873153522..3a1b7b04eb7 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -251,7 +251,8 @@ static ssize_t bonding_store_slaves(struct device *d, | |||
251 | 251 | ||
252 | /* Note: We can't hold bond->lock here, as bond_create grabs it. */ | 252 | /* Note: We can't hold bond->lock here, as bond_create grabs it. */ |
253 | 253 | ||
254 | rtnl_lock(); | 254 | if (!rtnl_trylock()) |
255 | return restart_syscall(); | ||
255 | down_write(&(bonding_rwsem)); | 256 | down_write(&(bonding_rwsem)); |
256 | 257 | ||
257 | sscanf(buffer, "%16s", command); /* IFNAMSIZ*/ | 258 | sscanf(buffer, "%16s", command); /* IFNAMSIZ*/ |
@@ -1171,7 +1172,8 @@ static ssize_t bonding_store_primary(struct device *d, | |||
1171 | struct slave *slave; | 1172 | struct slave *slave; |
1172 | struct bonding *bond = to_bond(d); | 1173 | struct bonding *bond = to_bond(d); |
1173 | 1174 | ||
1174 | rtnl_lock(); | 1175 | if (!rtnl_trylock()) |
1176 | return restart_syscall(); | ||
1175 | read_lock(&bond->lock); | 1177 | read_lock(&bond->lock); |
1176 | write_lock_bh(&bond->curr_slave_lock); | 1178 | write_lock_bh(&bond->curr_slave_lock); |
1177 | 1179 | ||
@@ -1288,7 +1290,8 @@ static ssize_t bonding_store_active_slave(struct device *d, | |||
1288 | struct slave *new_active = NULL; | 1290 | struct slave *new_active = NULL; |
1289 | struct bonding *bond = to_bond(d); | 1291 | struct bonding *bond = to_bond(d); |
1290 | 1292 | ||
1291 | rtnl_lock(); | 1293 | if (!rtnl_trylock()) |
1294 | return restart_syscall(); | ||
1292 | read_lock(&bond->lock); | 1295 | read_lock(&bond->lock); |
1293 | write_lock_bh(&bond->curr_slave_lock); | 1296 | write_lock_bh(&bond->curr_slave_lock); |
1294 | 1297 | ||