Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+17 −13
Original line number Original line Diff line number Diff line
@@ -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,
		}
		}
		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,
	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,


	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,
	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,
		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,
	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,
			 */
			 */
			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,
	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,
		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,
				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,