diff options
author | dingtianhong <dingtianhong@huawei.com> | 2013-10-15 04:28:42 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-17 15:32:03 -0400 |
commit | 4d1ae5fb752b2504cf2c3d79abdfb410a09ad928 (patch) | |
tree | 96e159c832423cfeda2d18aff65e2d2afea2d4a5 /drivers/net/bonding/bond_sysfs.c | |
parent | 28c719260da032c999ecb4b73ba56311c635ef4e (diff) |
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: Ding Tianhong <dingtianhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_sysfs.c')
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index e9249527e7e7..03bed0ca935e 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -179,7 +179,9 @@ static ssize_t bonding_show_slaves(struct device *d, | |||
179 | struct slave *slave; | 179 | struct slave *slave; |
180 | int res = 0; | 180 | int res = 0; |
181 | 181 | ||
182 | read_lock(&bond->lock); | 182 | if (!rtnl_trylock()) |
183 | return restart_syscall(); | ||
184 | |||
183 | bond_for_each_slave(bond, slave, iter) { | 185 | bond_for_each_slave(bond, slave, iter) { |
184 | if (res > (PAGE_SIZE - IFNAMSIZ)) { | 186 | if (res > (PAGE_SIZE - IFNAMSIZ)) { |
185 | /* not enough space for another interface name */ | 187 | /* not enough space for another interface name */ |
@@ -190,7 +192,9 @@ static ssize_t bonding_show_slaves(struct device *d, | |||
190 | } | 192 | } |
191 | res += sprintf(buf + res, "%s ", slave->dev->name); | 193 | res += sprintf(buf + res, "%s ", slave->dev->name); |
192 | } | 194 | } |
193 | read_unlock(&bond->lock); | 195 | |
196 | rtnl_unlock(); | ||
197 | |||
194 | if (res) | 198 | if (res) |
195 | buf[res-1] = '\n'; /* eat the leftover space */ | 199 | buf[res-1] = '\n'; /* eat the leftover space */ |
196 | 200 | ||
@@ -626,6 +630,9 @@ static ssize_t bonding_store_arp_targets(struct device *d, | |||
626 | unsigned long *targets_rx; | 630 | unsigned long *targets_rx; |
627 | int ind, i, j, ret = -EINVAL; | 631 | int ind, i, j, ret = -EINVAL; |
628 | 632 | ||
633 | if (!rtnl_trylock()) | ||
634 | return restart_syscall(); | ||
635 | |||
629 | targets = bond->params.arp_targets; | 636 | targets = bond->params.arp_targets; |
630 | newtarget = in_aton(buf + 1); | 637 | newtarget = in_aton(buf + 1); |
631 | /* look for adds */ | 638 | /* look for adds */ |
@@ -699,6 +706,7 @@ static ssize_t bonding_store_arp_targets(struct device *d, | |||
699 | 706 | ||
700 | ret = count; | 707 | ret = count; |
701 | out: | 708 | out: |
709 | rtnl_unlock(); | ||
702 | return ret; | 710 | return ret; |
703 | } | 711 | } |
704 | static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets); | 712 | 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 | if (!rtnl_trylock()) | 1475 | if (!rtnl_trylock()) |
1468 | return restart_syscall(); | 1476 | return restart_syscall(); |
1469 | 1477 | ||
1470 | read_lock(&bond->lock); | ||
1471 | bond_for_each_slave(bond, slave, iter) { | 1478 | bond_for_each_slave(bond, slave, iter) { |
1472 | if (res > (PAGE_SIZE - IFNAMSIZ - 6)) { | 1479 | if (res > (PAGE_SIZE - IFNAMSIZ - 6)) { |
1473 | /* not enough space for another interface_name:queue_id pair */ | 1480 | /* 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 | res += sprintf(buf + res, "%s:%d ", | 1486 | res += sprintf(buf + res, "%s:%d ", |
1480 | slave->dev->name, slave->queue_id); | 1487 | slave->dev->name, slave->queue_id); |
1481 | } | 1488 | } |
1482 | read_unlock(&bond->lock); | ||
1483 | if (res) | 1489 | if (res) |
1484 | buf[res-1] = '\n'; /* eat the leftover space */ | 1490 | buf[res-1] = '\n'; /* eat the leftover space */ |
1491 | |||
1485 | rtnl_unlock(); | 1492 | rtnl_unlock(); |
1486 | 1493 | ||
1487 | return res; | 1494 | return res; |
@@ -1530,8 +1537,6 @@ static ssize_t bonding_store_queue_id(struct device *d, | |||
1530 | if (!sdev) | 1537 | if (!sdev) |
1531 | goto err_no_cmd; | 1538 | goto err_no_cmd; |
1532 | 1539 | ||
1533 | read_lock(&bond->lock); | ||
1534 | |||
1535 | /* Search for thes slave and check for duplicate qids */ | 1540 | /* Search for thes slave and check for duplicate qids */ |
1536 | update_slave = NULL; | 1541 | update_slave = NULL; |
1537 | bond_for_each_slave(bond, slave, iter) { | 1542 | bond_for_each_slave(bond, slave, iter) { |
@@ -1542,23 +1547,20 @@ static ssize_t bonding_store_queue_id(struct device *d, | |||
1542 | */ | 1547 | */ |
1543 | update_slave = slave; | 1548 | update_slave = slave; |
1544 | else if (qid && qid == slave->queue_id) { | 1549 | else if (qid && qid == slave->queue_id) { |
1545 | goto err_no_cmd_unlock; | 1550 | goto err_no_cmd; |
1546 | } | 1551 | } |
1547 | } | 1552 | } |
1548 | 1553 | ||
1549 | if (!update_slave) | 1554 | if (!update_slave) |
1550 | goto err_no_cmd_unlock; | 1555 | goto err_no_cmd; |
1551 | 1556 | ||
1552 | /* Actually set the qids for the slave */ | 1557 | /* Actually set the qids for the slave */ |
1553 | update_slave->queue_id = qid; | 1558 | update_slave->queue_id = qid; |
1554 | 1559 | ||
1555 | read_unlock(&bond->lock); | ||
1556 | out: | 1560 | out: |
1557 | rtnl_unlock(); | 1561 | rtnl_unlock(); |
1558 | return ret; | 1562 | return ret; |
1559 | 1563 | ||
1560 | err_no_cmd_unlock: | ||
1561 | read_unlock(&bond->lock); | ||
1562 | err_no_cmd: | 1564 | err_no_cmd: |
1563 | pr_info("invalid input for queue_id set for %s.\n", | 1565 | pr_info("invalid input for queue_id set for %s.\n", |
1564 | bond->dev->name); | 1566 | bond->dev->name); |
@@ -1591,6 +1593,9 @@ static ssize_t bonding_store_slaves_active(struct device *d, | |||
1591 | struct list_head *iter; | 1593 | struct list_head *iter; |
1592 | struct slave *slave; | 1594 | struct slave *slave; |
1593 | 1595 | ||
1596 | if (!rtnl_trylock()) | ||
1597 | return restart_syscall(); | ||
1598 | |||
1594 | if (sscanf(buf, "%d", &new_value) != 1) { | 1599 | if (sscanf(buf, "%d", &new_value) != 1) { |
1595 | pr_err("%s: no all_slaves_active value specified.\n", | 1600 | pr_err("%s: no all_slaves_active value specified.\n", |
1596 | bond->dev->name); | 1601 | bond->dev->name); |
@@ -1610,7 +1615,6 @@ static ssize_t bonding_store_slaves_active(struct device *d, | |||
1610 | goto out; | 1615 | goto out; |
1611 | } | 1616 | } |
1612 | 1617 | ||
1613 | read_lock(&bond->lock); | ||
1614 | bond_for_each_slave(bond, slave, iter) { | 1618 | bond_for_each_slave(bond, slave, iter) { |
1615 | if (!bond_is_active_slave(slave)) { | 1619 | if (!bond_is_active_slave(slave)) { |
1616 | if (new_value) | 1620 | if (new_value) |
@@ -1619,8 +1623,8 @@ static ssize_t bonding_store_slaves_active(struct device *d, | |||
1619 | slave->inactive = 1; | 1623 | slave->inactive = 1; |
1620 | } | 1624 | } |
1621 | } | 1625 | } |
1622 | read_unlock(&bond->lock); | ||
1623 | out: | 1626 | out: |
1627 | rtnl_unlock(); | ||
1624 | return ret; | 1628 | return ret; |
1625 | } | 1629 | } |
1626 | static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR, | 1630 | static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR, |