aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_alb.c23
-rw-r--r--drivers/net/bonding/bond_main.c64
-rw-r--r--drivers/net/bonding/bond_sysfs.c66
-rw-r--r--drivers/net/bonding/bonding.h4
4 files changed, 94 insertions, 63 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 25b8dbf6cfd7..b57bc9467dbe 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -979,7 +979,7 @@ static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct
979/* 979/*
980 * Send learning packets after MAC address swap. 980 * Send learning packets after MAC address swap.
981 * 981 *
982 * Called with RTNL and bond->lock held for read. 982 * Called with RTNL and no other locks
983 */ 983 */
984static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1, 984static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
985 struct slave *slave2) 985 struct slave *slave2)
@@ -987,6 +987,8 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
987 int slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2)); 987 int slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
988 struct slave *disabled_slave = NULL; 988 struct slave *disabled_slave = NULL;
989 989
990 ASSERT_RTNL();
991
990 /* fasten the change in the switch */ 992 /* fasten the change in the switch */
991 if (SLAVE_IS_OK(slave1)) { 993 if (SLAVE_IS_OK(slave1)) {
992 alb_send_learning_packets(slave1, slave1->dev->dev_addr); 994 alb_send_learning_packets(slave1, slave1->dev->dev_addr);
@@ -1031,7 +1033,7 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
1031 * a slave that has @slave's permanet address as its current address. 1033 * a slave that has @slave's permanet address as its current address.
1032 * We'll make sure that that slave no longer uses @slave's permanent address. 1034 * We'll make sure that that slave no longer uses @slave's permanent address.
1033 * 1035 *
1034 * Caller must hold bond lock 1036 * Caller must hold RTNL and no other locks
1035 */ 1037 */
1036static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave) 1038static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave)
1037{ 1039{
@@ -1542,7 +1544,12 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
1542 return 0; 1544 return 0;
1543} 1545}
1544 1546
1545/* Caller must hold bond lock for write */ 1547/*
1548 * Remove slave from tlb and rlb hash tables, and fix up MAC addresses
1549 * if necessary.
1550 *
1551 * Caller must hold RTNL and no other locks
1552 */
1546void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave) 1553void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
1547{ 1554{
1548 if (bond->slave_cnt > 1) { 1555 if (bond->slave_cnt > 1) {
@@ -1601,9 +1608,6 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
1601 struct slave *swap_slave; 1608 struct slave *swap_slave;
1602 int i; 1609 int i;
1603 1610
1604 if (new_slave)
1605 ASSERT_RTNL();
1606
1607 if (bond->curr_active_slave == new_slave) { 1611 if (bond->curr_active_slave == new_slave) {
1608 return; 1612 return;
1609 } 1613 }
@@ -1649,6 +1653,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
1649 write_unlock_bh(&bond->curr_slave_lock); 1653 write_unlock_bh(&bond->curr_slave_lock);
1650 read_unlock(&bond->lock); 1654 read_unlock(&bond->lock);
1651 1655
1656 ASSERT_RTNL();
1657
1652 /* curr_active_slave must be set before calling alb_swap_mac_addr */ 1658 /* curr_active_slave must be set before calling alb_swap_mac_addr */
1653 if (swap_slave) { 1659 if (swap_slave) {
1654 /* swap mac address */ 1660 /* swap mac address */
@@ -1659,12 +1665,11 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
1659 bond->alb_info.rlb_enabled); 1665 bond->alb_info.rlb_enabled);
1660 } 1666 }
1661 1667
1662 read_lock(&bond->lock);
1663
1664 if (swap_slave) { 1668 if (swap_slave) {
1665 alb_fasten_mac_swap(bond, swap_slave, new_slave); 1669 alb_fasten_mac_swap(bond, swap_slave, new_slave);
1670 read_lock(&bond->lock);
1666 } else { 1671 } else {
1667 /* fasten bond mac on new current slave */ 1672 read_lock(&bond->lock);
1668 alb_send_learning_packets(new_slave, bond->dev->dev_addr); 1673 alb_send_learning_packets(new_slave, bond->dev->dev_addr);
1669 } 1674 }
1670 1675
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index b0b26036266b..49a198206e3d 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1746,7 +1746,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1746 * has been cleared (if our_slave == old_current), 1746 * has been cleared (if our_slave == old_current),
1747 * but before a new active slave is selected. 1747 * but before a new active slave is selected.
1748 */ 1748 */
1749 write_unlock_bh(&bond->lock);
1749 bond_alb_deinit_slave(bond, slave); 1750 bond_alb_deinit_slave(bond, slave);
1751 write_lock_bh(&bond->lock);
1750 } 1752 }
1751 1753
1752 if (oldcurrent == slave) { 1754 if (oldcurrent == slave) {
@@ -1905,6 +1907,12 @@ static int bond_release_all(struct net_device *bond_dev)
1905 slave_dev = slave->dev; 1907 slave_dev = slave->dev;
1906 bond_detach_slave(bond, slave); 1908 bond_detach_slave(bond, slave);
1907 1909
1910 /* now that the slave is detached, unlock and perform
1911 * all the undo steps that should not be called from
1912 * within a lock.
1913 */
1914 write_unlock_bh(&bond->lock);
1915
1908 if ((bond->params.mode == BOND_MODE_TLB) || 1916 if ((bond->params.mode == BOND_MODE_TLB) ||
1909 (bond->params.mode == BOND_MODE_ALB)) { 1917 (bond->params.mode == BOND_MODE_ALB)) {
1910 /* must be called only after the slave 1918 /* must be called only after the slave
@@ -1915,12 +1923,6 @@ static int bond_release_all(struct net_device *bond_dev)
1915 1923
1916 bond_compute_features(bond); 1924 bond_compute_features(bond);
1917 1925
1918 /* now that the slave is detached, unlock and perform
1919 * all the undo steps that should not be called from
1920 * within a lock.
1921 */
1922 write_unlock_bh(&bond->lock);
1923
1924 bond_destroy_slave_symlinks(bond_dev, slave_dev); 1926 bond_destroy_slave_symlinks(bond_dev, slave_dev);
1925 bond_del_vlans_from_slave(bond, slave_dev); 1927 bond_del_vlans_from_slave(bond, slave_dev);
1926 1928
@@ -2384,7 +2386,9 @@ void bond_mii_monitor(struct work_struct *work)
2384 rtnl_lock(); 2386 rtnl_lock();
2385 read_lock(&bond->lock); 2387 read_lock(&bond->lock);
2386 __bond_mii_monitor(bond, 1); 2388 __bond_mii_monitor(bond, 1);
2387 rtnl_unlock(); 2389 read_unlock(&bond->lock);
2390 rtnl_unlock(); /* might sleep, hold no other locks */
2391 read_lock(&bond->lock);
2388 } 2392 }
2389 2393
2390 delay = ((bond->params.miimon * HZ) / 1000) ? : 1; 2394 delay = ((bond->params.miimon * HZ) / 1000) ? : 1;
@@ -3399,9 +3403,7 @@ static int bond_master_netdev_event(unsigned long event, struct net_device *bond
3399 case NETDEV_CHANGENAME: 3403 case NETDEV_CHANGENAME:
3400 return bond_event_changename(event_bond); 3404 return bond_event_changename(event_bond);
3401 case NETDEV_UNREGISTER: 3405 case NETDEV_UNREGISTER:
3402 /* 3406 bond_release_all(event_bond->dev);
3403 * TODO: remove a bond from the list?
3404 */
3405 break; 3407 break;
3406 default: 3408 default:
3407 break; 3409 break;
@@ -4540,18 +4542,27 @@ static void bond_free_all(void)
4540 4542
4541/* 4543/*
4542 * Convert string input module parms. Accept either the 4544 * Convert string input module parms. Accept either the
4543 * number of the mode or its string name. 4545 * number of the mode or its string name. A bit complicated because
4546 * some mode names are substrings of other names, and calls from sysfs
4547 * may have whitespace in the name (trailing newlines, for example).
4544 */ 4548 */
4545int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl) 4549int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl)
4546{ 4550{
4547 int i; 4551 int mode = -1, i, rv;
4552 char modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };
4553
4554 rv = sscanf(buf, "%d", &mode);
4555 if (!rv) {
4556 rv = sscanf(buf, "%20s", modestr);
4557 if (!rv)
4558 return -1;
4559 }
4548 4560
4549 for (i = 0; tbl[i].modename; i++) { 4561 for (i = 0; tbl[i].modename; i++) {
4550 if ((isdigit(*mode_arg) && 4562 if (mode == tbl[i].mode)
4551 tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) || 4563 return tbl[i].mode;
4552 (strcmp(mode_arg, tbl[i].modename) == 0)) { 4564 if (strcmp(modestr, tbl[i].modename) == 0)
4553 return tbl[i].mode; 4565 return tbl[i].mode;
4554 }
4555 } 4566 }
4556 4567
4557 return -1; 4568 return -1;
@@ -4865,9 +4876,22 @@ static struct lock_class_key bonding_netdev_xmit_lock_key;
4865int bond_create(char *name, struct bond_params *params, struct bonding **newbond) 4876int bond_create(char *name, struct bond_params *params, struct bonding **newbond)
4866{ 4877{
4867 struct net_device *bond_dev; 4878 struct net_device *bond_dev;
4879 struct bonding *bond, *nxt;
4868 int res; 4880 int res;
4869 4881
4870 rtnl_lock(); 4882 rtnl_lock();
4883 down_write(&bonding_rwsem);
4884
4885 /* Check to see if the bond already exists. */
4886 list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
4887 if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
4888 printk(KERN_ERR DRV_NAME
4889 ": cannot add bond %s; it already exists\n",
4890 name);
4891 res = -EPERM;
4892 goto out_rtnl;
4893 }
4894
4871 bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "", 4895 bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
4872 ether_setup); 4896 ether_setup);
4873 if (!bond_dev) { 4897 if (!bond_dev) {
@@ -4906,10 +4930,12 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
4906 4930
4907 netif_carrier_off(bond_dev); 4931 netif_carrier_off(bond_dev);
4908 4932
4933 up_write(&bonding_rwsem);
4909 rtnl_unlock(); /* allows sysfs registration of net device */ 4934 rtnl_unlock(); /* allows sysfs registration of net device */
4910 res = bond_create_sysfs_entry(bond_dev->priv); 4935 res = bond_create_sysfs_entry(bond_dev->priv);
4911 if (res < 0) { 4936 if (res < 0) {
4912 rtnl_lock(); 4937 rtnl_lock();
4938 down_write(&bonding_rwsem);
4913 goto out_bond; 4939 goto out_bond;
4914 } 4940 }
4915 4941
@@ -4920,6 +4946,7 @@ out_bond:
4920out_netdev: 4946out_netdev:
4921 free_netdev(bond_dev); 4947 free_netdev(bond_dev);
4922out_rtnl: 4948out_rtnl:
4949 up_write(&bonding_rwsem);
4923 rtnl_unlock(); 4950 rtnl_unlock();
4924 return res; 4951 return res;
4925} 4952}
@@ -4940,6 +4967,9 @@ static int __init bonding_init(void)
4940#ifdef CONFIG_PROC_FS 4967#ifdef CONFIG_PROC_FS
4941 bond_create_proc_dir(); 4968 bond_create_proc_dir();
4942#endif 4969#endif
4970
4971 init_rwsem(&bonding_rwsem);
4972
4943 for (i = 0; i < max_bonds; i++) { 4973 for (i = 0; i < max_bonds; i++) {
4944 res = bond_create(NULL, &bonding_defaults, NULL); 4974 res = bond_create(NULL, &bonding_defaults, NULL);
4945 if (res) 4975 if (res)
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 11b76b352415..90a1f31e8e63 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -109,11 +109,10 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
109{ 109{
110 char command[IFNAMSIZ + 1] = {0, }; 110 char command[IFNAMSIZ + 1] = {0, };
111 char *ifname; 111 char *ifname;
112 int res = count; 112 int rv, res = count;
113 struct bonding *bond; 113 struct bonding *bond;
114 struct bonding *nxt; 114 struct bonding *nxt;
115 115
116 down_write(&(bonding_rwsem));
117 sscanf(buffer, "%16s", command); /* IFNAMSIZ*/ 116 sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
118 ifname = command + 1; 117 ifname = command + 1;
119 if ((strlen(command) <= 1) || 118 if ((strlen(command) <= 1) ||
@@ -121,39 +120,28 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
121 goto err_no_cmd; 120 goto err_no_cmd;
122 121
123 if (command[0] == '+') { 122 if (command[0] == '+') {
124
125 /* Check to see if the bond already exists. */
126 list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
127 if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
128 printk(KERN_ERR DRV_NAME
129 ": cannot add bond %s; it already exists\n",
130 ifname);
131 res = -EPERM;
132 goto out;
133 }
134
135 printk(KERN_INFO DRV_NAME 123 printk(KERN_INFO DRV_NAME
136 ": %s is being created...\n", ifname); 124 ": %s is being created...\n", ifname);
137 if (bond_create(ifname, &bonding_defaults, &bond)) { 125 rv = bond_create(ifname, &bonding_defaults, &bond);
138 printk(KERN_INFO DRV_NAME 126 if (rv) {
139 ": %s interface already exists. Bond creation failed.\n", 127 printk(KERN_INFO DRV_NAME ": Bond creation failed.\n");
140 ifname); 128 res = rv;
141 res = -EPERM;
142 } 129 }
143 goto out; 130 goto out;
144 } 131 }
145 132
146 if (command[0] == '-') { 133 if (command[0] == '-') {
134 rtnl_lock();
135 down_write(&bonding_rwsem);
136
147 list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) 137 list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
148 if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) { 138 if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
149 rtnl_lock();
150 /* check the ref count on the bond's kobject. 139 /* check the ref count on the bond's kobject.
151 * If it's > expected, then there's a file open, 140 * If it's > expected, then there's a file open,
152 * and we have to fail. 141 * and we have to fail.
153 */ 142 */
154 if (atomic_read(&bond->dev->dev.kobj.kref.refcount) 143 if (atomic_read(&bond->dev->dev.kobj.kref.refcount)
155 > expected_refcount){ 144 > expected_refcount){
156 rtnl_unlock();
157 printk(KERN_INFO DRV_NAME 145 printk(KERN_INFO DRV_NAME
158 ": Unable remove bond %s due to open references.\n", 146 ": Unable remove bond %s due to open references.\n",
159 ifname); 147 ifname);
@@ -164,6 +152,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
164 ": %s is being deleted...\n", 152 ": %s is being deleted...\n",
165 bond->dev->name); 153 bond->dev->name);
166 bond_destroy(bond); 154 bond_destroy(bond);
155 up_write(&bonding_rwsem);
167 rtnl_unlock(); 156 rtnl_unlock();
168 goto out; 157 goto out;
169 } 158 }
@@ -171,6 +160,8 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
171 printk(KERN_ERR DRV_NAME 160 printk(KERN_ERR DRV_NAME
172 ": unable to delete non-existent bond %s\n", ifname); 161 ": unable to delete non-existent bond %s\n", ifname);
173 res = -ENODEV; 162 res = -ENODEV;
163 up_write(&bonding_rwsem);
164 rtnl_unlock();
174 goto out; 165 goto out;
175 } 166 }
176 167
@@ -183,7 +174,6 @@ err_no_cmd:
183 * get called forever, which is bad. 174 * get called forever, which is bad.
184 */ 175 */
185out: 176out:
186 up_write(&(bonding_rwsem));
187 return res; 177 return res;
188} 178}
189/* class attribute for bond_masters file. This ends up in /sys/class/net */ 179/* class attribute for bond_masters file. This ends up in /sys/class/net */
@@ -271,6 +261,9 @@ static ssize_t bonding_store_slaves(struct device *d,
271 261
272 /* Note: We can't hold bond->lock here, as bond_create grabs it. */ 262 /* Note: We can't hold bond->lock here, as bond_create grabs it. */
273 263
264 rtnl_lock();
265 down_write(&(bonding_rwsem));
266
274 sscanf(buffer, "%16s", command); /* IFNAMSIZ*/ 267 sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
275 ifname = command + 1; 268 ifname = command + 1;
276 if ((strlen(command) <= 1) || 269 if ((strlen(command) <= 1) ||
@@ -336,12 +329,10 @@ static ssize_t bonding_store_slaves(struct device *d,
336 dev->mtu = bond->dev->mtu; 329 dev->mtu = bond->dev->mtu;
337 } 330 }
338 } 331 }
339 rtnl_lock();
340 res = bond_enslave(bond->dev, dev); 332 res = bond_enslave(bond->dev, dev);
341 bond_for_each_slave(bond, slave, i) 333 bond_for_each_slave(bond, slave, i)
342 if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) 334 if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0)
343 slave->original_mtu = original_mtu; 335 slave->original_mtu = original_mtu;
344 rtnl_unlock();
345 if (res) { 336 if (res) {
346 ret = res; 337 ret = res;
347 } 338 }
@@ -359,12 +350,10 @@ static ssize_t bonding_store_slaves(struct device *d,
359 if (dev) { 350 if (dev) {
360 printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n", 351 printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
361 bond->dev->name, dev->name); 352 bond->dev->name, dev->name);
362 rtnl_lock();
363 if (bond->setup_by_slave) 353 if (bond->setup_by_slave)
364 res = bond_release_and_destroy(bond->dev, dev); 354 res = bond_release_and_destroy(bond->dev, dev);
365 else 355 else
366 res = bond_release(bond->dev, dev); 356 res = bond_release(bond->dev, dev);
367 rtnl_unlock();
368 if (res) { 357 if (res) {
369 ret = res; 358 ret = res;
370 goto out; 359 goto out;
@@ -389,6 +378,8 @@ err_no_cmd:
389 ret = -EPERM; 378 ret = -EPERM;
390 379
391out: 380out:
381 up_write(&(bonding_rwsem));
382 rtnl_unlock();
392 return ret; 383 return ret;
393} 384}
394 385
@@ -423,7 +414,7 @@ static ssize_t bonding_store_mode(struct device *d,
423 goto out; 414 goto out;
424 } 415 }
425 416
426 new_value = bond_parse_parm((char *)buf, bond_mode_tbl); 417 new_value = bond_parse_parm(buf, bond_mode_tbl);
427 if (new_value < 0) { 418 if (new_value < 0) {
428 printk(KERN_ERR DRV_NAME 419 printk(KERN_ERR DRV_NAME
429 ": %s: Ignoring invalid mode value %.*s.\n", 420 ": %s: Ignoring invalid mode value %.*s.\n",
@@ -478,7 +469,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
478 goto out; 469 goto out;
479 } 470 }
480 471
481 new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl); 472 new_value = bond_parse_parm(buf, xmit_hashtype_tbl);
482 if (new_value < 0) { 473 if (new_value < 0) {
483 printk(KERN_ERR DRV_NAME 474 printk(KERN_ERR DRV_NAME
484 ": %s: Ignoring invalid xmit hash policy value %.*s.\n", 475 ": %s: Ignoring invalid xmit hash policy value %.*s.\n",
@@ -518,7 +509,7 @@ static ssize_t bonding_store_arp_validate(struct device *d,
518 int new_value; 509 int new_value;
519 struct bonding *bond = to_bond(d); 510 struct bonding *bond = to_bond(d);
520 511
521 new_value = bond_parse_parm((char *)buf, arp_validate_tbl); 512 new_value = bond_parse_parm(buf, arp_validate_tbl);
522 if (new_value < 0) { 513 if (new_value < 0) {
523 printk(KERN_ERR DRV_NAME 514 printk(KERN_ERR DRV_NAME
524 ": %s: Ignoring invalid arp_validate value %s\n", 515 ": %s: Ignoring invalid arp_validate value %s\n",
@@ -941,7 +932,7 @@ static ssize_t bonding_store_lacp(struct device *d,
941 goto out; 932 goto out;
942 } 933 }
943 934
944 new_value = bond_parse_parm((char *)buf, bond_lacp_tbl); 935 new_value = bond_parse_parm(buf, bond_lacp_tbl);
945 936
946 if ((new_value == 1) || (new_value == 0)) { 937 if ((new_value == 1) || (new_value == 0)) {
947 bond->params.lacp_fast = new_value; 938 bond->params.lacp_fast = new_value;
@@ -1075,7 +1066,10 @@ static ssize_t bonding_store_primary(struct device *d,
1075 struct slave *slave; 1066 struct slave *slave;
1076 struct bonding *bond = to_bond(d); 1067 struct bonding *bond = to_bond(d);
1077 1068
1078 write_lock_bh(&bond->lock); 1069 rtnl_lock();
1070 read_lock(&bond->lock);
1071 write_lock_bh(&bond->curr_slave_lock);
1072
1079 if (!USES_PRIMARY(bond->params.mode)) { 1073 if (!USES_PRIMARY(bond->params.mode)) {
1080 printk(KERN_INFO DRV_NAME 1074 printk(KERN_INFO DRV_NAME
1081 ": %s: Unable to set primary slave; %s is in mode %d\n", 1075 ": %s: Unable to set primary slave; %s is in mode %d\n",
@@ -1109,8 +1103,8 @@ static ssize_t bonding_store_primary(struct device *d,
1109 } 1103 }
1110 } 1104 }
1111out: 1105out:
1112 write_unlock_bh(&bond->lock); 1106 write_unlock_bh(&bond->curr_slave_lock);
1113 1107 read_unlock(&bond->lock);
1114 rtnl_unlock(); 1108 rtnl_unlock();
1115 1109
1116 return count; 1110 return count;
@@ -1190,7 +1184,8 @@ static ssize_t bonding_store_active_slave(struct device *d,
1190 struct bonding *bond = to_bond(d); 1184 struct bonding *bond = to_bond(d);
1191 1185
1192 rtnl_lock(); 1186 rtnl_lock();
1193 write_lock_bh(&bond->lock); 1187 read_lock(&bond->lock);
1188 write_lock_bh(&bond->curr_slave_lock);
1194 1189
1195 if (!USES_PRIMARY(bond->params.mode)) { 1190 if (!USES_PRIMARY(bond->params.mode)) {
1196 printk(KERN_INFO DRV_NAME 1191 printk(KERN_INFO DRV_NAME
@@ -1247,7 +1242,8 @@ static ssize_t bonding_store_active_slave(struct device *d,
1247 } 1242 }
1248 } 1243 }
1249out: 1244out:
1250 write_unlock_bh(&bond->lock); 1245 write_unlock_bh(&bond->curr_slave_lock);
1246 read_unlock(&bond->lock);
1251 rtnl_unlock(); 1247 rtnl_unlock();
1252 1248
1253 return count; 1249 return count;
@@ -1418,8 +1414,6 @@ int bond_create_sysfs(void)
1418 int ret = 0; 1414 int ret = 0;
1419 struct bonding *firstbond; 1415 struct bonding *firstbond;
1420 1416
1421 init_rwsem(&bonding_rwsem);
1422
1423 /* get the netdev class pointer */ 1417 /* get the netdev class pointer */
1424 firstbond = container_of(bond_dev_list.next, struct bonding, bond_list); 1418 firstbond = container_of(bond_dev_list.next, struct bonding, bond_list);
1425 if (!firstbond) 1419 if (!firstbond)
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index e1e4734e23ce..6d83be49899a 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -141,6 +141,8 @@ struct bond_parm_tbl {
141 int mode; 141 int mode;
142}; 142};
143 143
144#define BOND_MAX_MODENAME_LEN 20
145
144struct vlan_entry { 146struct vlan_entry {
145 struct list_head vlan_list; 147 struct list_head vlan_list;
146 __be32 vlan_ip; 148 __be32 vlan_ip;
@@ -314,7 +316,7 @@ void bond_mii_monitor(struct work_struct *);
314void bond_loadbalance_arp_mon(struct work_struct *); 316void bond_loadbalance_arp_mon(struct work_struct *);
315void bond_activebackup_arp_mon(struct work_struct *); 317void bond_activebackup_arp_mon(struct work_struct *);
316void bond_set_mode_ops(struct bonding *bond, int mode); 318void bond_set_mode_ops(struct bonding *bond, int mode);
317int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl); 319int bond_parse_parm(const char *mode_arg, struct bond_parm_tbl *tbl);
318void bond_select_active_slave(struct bonding *bond); 320void bond_select_active_slave(struct bonding *bond);
319void bond_change_active_slave(struct bonding *bond, struct slave *new_active); 321void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
320void bond_register_arp(struct bonding *); 322void bond_register_arp(struct bonding *);