diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2009-05-13 16:57:25 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-05-18 22:15:57 -0700 |
commit | 336ca57c3b4e2b58ea3273e6d978ab3dfa387b4c (patch) | |
tree | e77d80f8e95e0fd15c987c1f1af1d8751800b3af /net/core/net-sysfs.c | |
parent | 690cc3ffe33ac4a2857583c22d4c6244ae11684d (diff) | |
download | lwn-336ca57c3b4e2b58ea3273e6d978ab3dfa387b4c.tar.gz lwn-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/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, 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(); |