diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2009-05-13 12:57:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-05-19 01:15:57 -0400 |
commit | 336ca57c3b4e2b58ea3273e6d978ab3dfa387b4c (patch) | |
tree | e77d80f8e95e0fd15c987c1f1af1d8751800b3af /net/core/net-sysfs.c | |
parent | 690cc3ffe33ac4a2857583c22d4c6244ae11684d (diff) |
net-sysfs: Use rtnl_trylock in sysfs methods.
The earlier patch to fix the deadlock between a network device going
away and writing to sysfs attributes was incomplete.
- It did not set signal_pending so we would leak ERSTARTSYS to user space.
- It used ERESTARTSYS which only restarts if sigaction configures it to.
- It did not cover store and show for ifalias.
So fix all of these up and use the new helper restart_syscall so we get
the details correct on what it takes.
Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/net-sysfs.c')
-rw-r--r-- | net/core/net-sysfs.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 2da59a0ac4ac..b9641e816eee 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -78,7 +78,7 @@ static ssize_t netdev_store(struct device *dev, struct device_attribute *attr, | |||
78 | goto err; | 78 | goto err; |
79 | 79 | ||
80 | if (!rtnl_trylock()) | 80 | if (!rtnl_trylock()) |
81 | return -ERESTARTSYS; | 81 | return restart_syscall(); |
82 | 82 | ||
83 | if (dev_isalive(net)) { | 83 | if (dev_isalive(net)) { |
84 | if ((ret = (*set)(net, new)) == 0) | 84 | if ((ret = (*set)(net, new)) == 0) |
@@ -225,7 +225,8 @@ static ssize_t store_ifalias(struct device *dev, struct device_attribute *attr, | |||
225 | if (len > 0 && buf[len - 1] == '\n') | 225 | if (len > 0 && buf[len - 1] == '\n') |
226 | --count; | 226 | --count; |
227 | 227 | ||
228 | rtnl_lock(); | 228 | if (!rtnl_trylock()) |
229 | return restart_syscall(); | ||
229 | ret = dev_set_alias(netdev, buf, count); | 230 | ret = dev_set_alias(netdev, buf, count); |
230 | rtnl_unlock(); | 231 | rtnl_unlock(); |
231 | 232 | ||
@@ -238,7 +239,8 @@ static ssize_t show_ifalias(struct device *dev, | |||
238 | const struct net_device *netdev = to_net_dev(dev); | 239 | const struct net_device *netdev = to_net_dev(dev); |
239 | ssize_t ret = 0; | 240 | ssize_t ret = 0; |
240 | 241 | ||
241 | rtnl_lock(); | 242 | if (!rtnl_trylock()) |
243 | return restart_syscall(); | ||
242 | if (netdev->ifalias) | 244 | if (netdev->ifalias) |
243 | ret = sprintf(buf, "%s\n", netdev->ifalias); | 245 | ret = sprintf(buf, "%s\n", netdev->ifalias); |
244 | rtnl_unlock(); | 246 | rtnl_unlock(); |