aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2009-05-13 16:57:25 +0000
committerDavid S. Miller <davem@davemloft.net>2009-05-18 22:15:57 -0700
commit336ca57c3b4e2b58ea3273e6d978ab3dfa387b4c (patch)
treee77d80f8e95e0fd15c987c1f1af1d8751800b3af /net
parentsyscall: Implement a convinience function restart_syscall (diff)
downloadlinux-dev-336ca57c3b4e2b58ea3273e6d978ab3dfa387b4c.tar.xz
linux-dev-336ca57c3b4e2b58ea3273e6d978ab3dfa387b4c.zip
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')
-rw-r--r--net/core/net-sysfs.c8
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,
goto err;
if (!rtnl_trylock())
- return -ERESTARTSYS;
+ return restart_syscall();
if (dev_isalive(net)) {
if ((ret = (*set)(net, new)) == 0)
@@ -225,7 +225,8 @@ static ssize_t store_ifalias(struct device *dev, struct device_attribute *attr,
if (len > 0 && buf[len - 1] == '\n')
--count;
- rtnl_lock();
+ if (!rtnl_trylock())
+ return restart_syscall();
ret = dev_set_alias(netdev, buf, count);
rtnl_unlock();
@@ -238,7 +239,8 @@ static ssize_t show_ifalias(struct device *dev,
const struct net_device *netdev = to_net_dev(dev);
ssize_t ret = 0;
- rtnl_lock();
+ if (!rtnl_trylock())
+ return restart_syscall();
if (netdev->ifalias)
ret = sprintf(buf, "%s\n", netdev->ifalias);
rtnl_unlock();