aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding/bond_sysfs.c')
-rw-r--r--drivers/net/bonding/bond_sysfs.c66
1 files changed, 30 insertions, 36 deletions
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)