aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-08-14 16:21:34 -0400
committerDavid S. Miller <davem@davemloft.net>2007-08-14 16:21:34 -0400
commit17120889b0706b69ae24cba3ef0a340dc3fb7edc (patch)
tree4c36e5f7592ba6b06fddc8ca141d1879326de564 /net
parent45241a7a07537266eec363593ef377a1e6b7db7f (diff)
[BRIDGE]: sysfs locking fix.
The stp change code generates "sleeping function called from invalid context" because rtnl_lock() called with BH disabled. This fixes it by not acquiring then dropping the bridge lock. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_sysfs_br.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 4f42263e0a8a..88f43003b193 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -147,20 +147,26 @@ static ssize_t show_stp_state(struct device *d,
147 return sprintf(buf, "%d\n", br->stp_enabled); 147 return sprintf(buf, "%d\n", br->stp_enabled);
148} 148}
149 149
150static void set_stp_state(struct net_bridge *br, unsigned long val)
151{
152 rtnl_lock();
153 spin_unlock_bh(&br->lock);
154 br_stp_set_enabled(br, val);
155 spin_lock_bh(&br->lock);
156 rtnl_unlock();
157}
158 150
159static ssize_t store_stp_state(struct device *d, 151static ssize_t store_stp_state(struct device *d,
160 struct device_attribute *attr, const char *buf, 152 struct device_attribute *attr, const char *buf,
161 size_t len) 153 size_t len)
162{ 154{
163 return store_bridge_parm(d, buf, len, set_stp_state); 155 struct net_bridge *br = to_bridge(d);
156 char *endp;
157 unsigned long val;
158
159 if (!capable(CAP_NET_ADMIN))
160 return -EPERM;
161
162 val = simple_strtoul(buf, &endp, 0);
163 if (endp == buf)
164 return -EINVAL;
165
166 rtnl_lock();
167 br_stp_set_enabled(br, val);
168 rtnl_unlock();
169
164} 170}
165static DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state, 171static DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state,
166 store_stp_state); 172 store_stp_state);