diff options
Diffstat (limited to 'drivers/net/bonding/bond_sysfs.c')
| -rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 40 | 
1 files changed, 14 insertions, 26 deletions
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index dc15d248443..1877ed7ca08 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -513,6 +513,8 @@ static ssize_t bonding_store_arp_interval(struct device *d,  	int new_value, ret = count;  	struct bonding *bond = to_bond(d); +	if (!rtnl_trylock()) +		return restart_syscall();  	if (sscanf(buf, "%d", &new_value) != 1) {  		pr_err("%s: no arp_interval value specified.\n",  		       bond->dev->name); @@ -539,10 +541,6 @@ static ssize_t bonding_store_arp_interval(struct device *d,  		pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",  			bond->dev->name, bond->dev->name);  		bond->params.miimon = 0; -		if (delayed_work_pending(&bond->mii_work)) { -			cancel_delayed_work(&bond->mii_work); -			flush_workqueue(bond->wq); -		}  	}  	if (!bond->params.arp_targets[0]) {  		pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", @@ -554,19 +552,12 @@ static ssize_t bonding_store_arp_interval(struct device *d,  		 * timer will get fired off when the open function  		 * is called.  		 */ -		if (!delayed_work_pending(&bond->arp_work)) { -			if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) -				INIT_DELAYED_WORK(&bond->arp_work, -						  bond_activebackup_arp_mon); -			else -				INIT_DELAYED_WORK(&bond->arp_work, -						  bond_loadbalance_arp_mon); - -			queue_delayed_work(bond->wq, &bond->arp_work, 0); -		} +		cancel_delayed_work_sync(&bond->mii_work); +		queue_delayed_work(bond->wq, &bond->arp_work, 0);  	}  out: +	rtnl_unlock();  	return ret;  }  static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR, @@ -962,6 +953,8 @@ static ssize_t bonding_store_miimon(struct device *d,  	int new_value, ret = count;  	struct bonding *bond = to_bond(d); +	if (!rtnl_trylock()) +		return restart_syscall();  	if (sscanf(buf, "%d", &new_value) != 1) {  		pr_err("%s: no miimon value specified.\n",  		       bond->dev->name); @@ -993,10 +986,6 @@ static ssize_t bonding_store_miimon(struct device *d,  				bond->params.arp_validate =  					BOND_ARP_VALIDATE_NONE;  			} -			if (delayed_work_pending(&bond->arp_work)) { -				cancel_delayed_work(&bond->arp_work); -				flush_workqueue(bond->wq); -			}  		}  		if (bond->dev->flags & IFF_UP) { @@ -1005,15 +994,12 @@ static ssize_t bonding_store_miimon(struct device *d,  			 * timer will get fired off when the open function  			 * is called.  			 */ -			if (!delayed_work_pending(&bond->mii_work)) { -				INIT_DELAYED_WORK(&bond->mii_work, -						  bond_mii_monitor); -				queue_delayed_work(bond->wq, -						   &bond->mii_work, 0); -			} +			cancel_delayed_work_sync(&bond->arp_work); +			queue_delayed_work(bond->wq, &bond->mii_work, 0);  		}  	}  out: +	rtnl_unlock();  	return ret;  }  static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, @@ -1060,7 +1046,7 @@ static ssize_t bonding_store_primary(struct device *d,  		goto out;  	} -	sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ +	sscanf(buf, "%15s", ifname); /* IFNAMSIZ */  	/* check to see if we are clearing primary */  	if (!strlen(ifname) || buf[0] == '\n') { @@ -1237,7 +1223,7 @@ static ssize_t bonding_store_active_slave(struct device *d,  		goto out;  	} -	sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ +	sscanf(buf, "%15s", ifname); /* IFNAMSIZ */  	/* check to see if we are clearing active */  	if (!strlen(ifname) || buf[0] == '\n') { @@ -1582,6 +1568,7 @@ static ssize_t bonding_store_slaves_active(struct device *d,  		goto out;  	} +	read_lock(&bond->lock);  	bond_for_each_slave(bond, slave, i) {  		if (!bond_is_active_slave(slave)) {  			if (new_value) @@ -1590,6 +1577,7 @@ static ssize_t bonding_store_slaves_active(struct device *d,  				slave->inactive = 1;  		}  	} +	read_unlock(&bond->lock);  out:  	return ret;  }  |