Commit 4d1ae5fb authored by dingtianhong's avatar dingtianhong Committed by David S. Miller

bonding: add rtnl lock and remove read lock for bond sysfs

The bond_for_each_slave() will not be protected by read_lock(),
only protected by rtnl_lock(), so need to replace read_lock()
with rtnl_lock().
Signed-off-by: default avatarDing Tianhong <dingtianhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 28c71926
...@@ -179,7 +179,9 @@ static ssize_t bonding_show_slaves(struct device *d, ...@@ -179,7 +179,9 @@ static ssize_t bonding_show_slaves(struct device *d,
struct slave *slave; struct slave *slave;
int res = 0; int res = 0;
read_lock(&bond->lock); if (!rtnl_trylock())
return restart_syscall();
bond_for_each_slave(bond, slave, iter) { bond_for_each_slave(bond, slave, iter) {
if (res > (PAGE_SIZE - IFNAMSIZ)) { if (res > (PAGE_SIZE - IFNAMSIZ)) {
/* not enough space for another interface name */ /* not enough space for another interface name */
...@@ -190,7 +192,9 @@ static ssize_t bonding_show_slaves(struct device *d, ...@@ -190,7 +192,9 @@ static ssize_t bonding_show_slaves(struct device *d,
} }
res += sprintf(buf + res, "%s ", slave->dev->name); res += sprintf(buf + res, "%s ", slave->dev->name);
} }
read_unlock(&bond->lock);
rtnl_unlock();
if (res) if (res)
buf[res-1] = '\n'; /* eat the leftover space */ buf[res-1] = '\n'; /* eat the leftover space */
...@@ -626,6 +630,9 @@ static ssize_t bonding_store_arp_targets(struct device *d, ...@@ -626,6 +630,9 @@ static ssize_t bonding_store_arp_targets(struct device *d,
unsigned long *targets_rx; unsigned long *targets_rx;
int ind, i, j, ret = -EINVAL; int ind, i, j, ret = -EINVAL;
if (!rtnl_trylock())
return restart_syscall();
targets = bond->params.arp_targets; targets = bond->params.arp_targets;
newtarget = in_aton(buf + 1); newtarget = in_aton(buf + 1);
/* look for adds */ /* look for adds */
...@@ -699,6 +706,7 @@ static ssize_t bonding_store_arp_targets(struct device *d, ...@@ -699,6 +706,7 @@ static ssize_t bonding_store_arp_targets(struct device *d,
ret = count; ret = count;
out: out:
rtnl_unlock();
return ret; return ret;
} }
static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets); static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);
...@@ -1467,7 +1475,6 @@ static ssize_t bonding_show_queue_id(struct device *d, ...@@ -1467,7 +1475,6 @@ static ssize_t bonding_show_queue_id(struct device *d,
if (!rtnl_trylock()) if (!rtnl_trylock())
return restart_syscall(); return restart_syscall();
read_lock(&bond->lock);
bond_for_each_slave(bond, slave, iter) { bond_for_each_slave(bond, slave, iter) {
if (res > (PAGE_SIZE - IFNAMSIZ - 6)) { if (res > (PAGE_SIZE - IFNAMSIZ - 6)) {
/* not enough space for another interface_name:queue_id pair */ /* not enough space for another interface_name:queue_id pair */
...@@ -1479,9 +1486,9 @@ static ssize_t bonding_show_queue_id(struct device *d, ...@@ -1479,9 +1486,9 @@ static ssize_t bonding_show_queue_id(struct device *d,
res += sprintf(buf + res, "%s:%d ", res += sprintf(buf + res, "%s:%d ",
slave->dev->name, slave->queue_id); slave->dev->name, slave->queue_id);
} }
read_unlock(&bond->lock);
if (res) if (res)
buf[res-1] = '\n'; /* eat the leftover space */ buf[res-1] = '\n'; /* eat the leftover space */
rtnl_unlock(); rtnl_unlock();
return res; return res;
...@@ -1530,8 +1537,6 @@ static ssize_t bonding_store_queue_id(struct device *d, ...@@ -1530,8 +1537,6 @@ static ssize_t bonding_store_queue_id(struct device *d,
if (!sdev) if (!sdev)
goto err_no_cmd; goto err_no_cmd;
read_lock(&bond->lock);
/* Search for thes slave and check for duplicate qids */ /* Search for thes slave and check for duplicate qids */
update_slave = NULL; update_slave = NULL;
bond_for_each_slave(bond, slave, iter) { bond_for_each_slave(bond, slave, iter) {
...@@ -1542,23 +1547,20 @@ static ssize_t bonding_store_queue_id(struct device *d, ...@@ -1542,23 +1547,20 @@ static ssize_t bonding_store_queue_id(struct device *d,
*/ */
update_slave = slave; update_slave = slave;
else if (qid && qid == slave->queue_id) { else if (qid && qid == slave->queue_id) {
goto err_no_cmd_unlock; goto err_no_cmd;
} }
} }
if (!update_slave) if (!update_slave)
goto err_no_cmd_unlock; goto err_no_cmd;
/* Actually set the qids for the slave */ /* Actually set the qids for the slave */
update_slave->queue_id = qid; update_slave->queue_id = qid;
read_unlock(&bond->lock);
out: out:
rtnl_unlock(); rtnl_unlock();
return ret; return ret;
err_no_cmd_unlock:
read_unlock(&bond->lock);
err_no_cmd: err_no_cmd:
pr_info("invalid input for queue_id set for %s.\n", pr_info("invalid input for queue_id set for %s.\n",
bond->dev->name); bond->dev->name);
...@@ -1591,6 +1593,9 @@ static ssize_t bonding_store_slaves_active(struct device *d, ...@@ -1591,6 +1593,9 @@ static ssize_t bonding_store_slaves_active(struct device *d,
struct list_head *iter; struct list_head *iter;
struct slave *slave; struct slave *slave;
if (!rtnl_trylock())
return restart_syscall();
if (sscanf(buf, "%d", &new_value) != 1) { if (sscanf(buf, "%d", &new_value) != 1) {
pr_err("%s: no all_slaves_active value specified.\n", pr_err("%s: no all_slaves_active value specified.\n",
bond->dev->name); bond->dev->name);
...@@ -1610,7 +1615,6 @@ static ssize_t bonding_store_slaves_active(struct device *d, ...@@ -1610,7 +1615,6 @@ static ssize_t bonding_store_slaves_active(struct device *d,
goto out; goto out;
} }
read_lock(&bond->lock);
bond_for_each_slave(bond, slave, iter) { bond_for_each_slave(bond, slave, iter) {
if (!bond_is_active_slave(slave)) { if (!bond_is_active_slave(slave)) {
if (new_value) if (new_value)
...@@ -1619,8 +1623,8 @@ static ssize_t bonding_store_slaves_active(struct device *d, ...@@ -1619,8 +1623,8 @@ static ssize_t bonding_store_slaves_active(struct device *d,
slave->inactive = 1; slave->inactive = 1;
} }
} }
read_unlock(&bond->lock);
out: out:
rtnl_unlock();
return ret; return ret;
} }
static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR, static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment