Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 150955
b: refs/heads/master
c: 373500d
h: refs/heads/master
i:
  150953: 62f66b4
  150951: c79389a
v: v3
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Jun 14, 2009
1 parent abdb84a commit 14f16e7
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 54 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6d7ab43ccce5fddeca945ba6b06ba32cda4e3355
refs/heads/master: 373500db927706d1f60785aff40b9884f789b01a
15 changes: 6 additions & 9 deletions trunk/drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5064,19 +5064,16 @@ static void bond_set_lockdep_class(struct net_device *dev)
int bond_create(const char *name)
{
struct net_device *bond_dev;
struct bonding *bond;
int res;

rtnl_lock();
/* Check to see if the bond already exists. */
if (name) {
list_for_each_entry(bond, &bond_dev_list, bond_list)
if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
pr_err(DRV_NAME ": cannot add bond %s;"
" it already exists\n", name);
res = -EPERM;
goto out_rtnl;
}
/* FIXME: pass netns from caller */
if (name && __dev_get_by_name(&init_net, name)) {
pr_err(DRV_NAME ": cannot add bond %s; already exists\n",
name);
res = -EEXIST;
goto out_rtnl;
}

bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
Expand Down
95 changes: 51 additions & 44 deletions trunk/drivers/net/bonding/bond_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ static ssize_t bonding_show_bonds(struct class *cls, char *buf)
return res;
}

static struct net_device *bond_get_by_name(const char *ifname)
{
struct bonding *bond;

list_for_each_entry(bond, &bond_dev_list, bond_list) {
if (strncmp(bond->dev->name, ifname, IFNAMSIZ) == 0)
return bond->dev;
}
return NULL;
}

/*
* "store" function for the bond_masters attribute. This is what
* creates and deletes entire bonds.
Expand All @@ -82,7 +93,6 @@ static ssize_t bonding_store_bonds(struct class *cls,
char command[IFNAMSIZ + 1] = {0, };
char *ifname;
int rv, res = count;
struct bonding *bond;

sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
ifname = command + 1;
Expand All @@ -98,41 +108,35 @@ static ssize_t bonding_store_bonds(struct class *cls,
pr_info(DRV_NAME ": Bond creation failed.\n");
res = rv;
}
goto out;
}
} else if (command[0] == '-') {
struct net_device *bond_dev;

if (command[0] == '-') {
rtnl_lock();
bond_dev = bond_get_by_name(ifname);
if (bond_dev) {
pr_info(DRV_NAME ": %s is being deleted...\n",
ifname);
unregister_netdevice(bond_dev);
} else {
pr_err(DRV_NAME ": unable to delete non-existent %s\n",
ifname);
res = -ENODEV;
}
rtnl_unlock();
} else
goto err_no_cmd;

list_for_each_entry(bond, &bond_dev_list, bond_list)
if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
pr_info(DRV_NAME
": %s is being deleted...\n",
bond->dev->name);
unregister_netdevice(bond->dev);
goto out_unlock;
}

pr_err(DRV_NAME
": unable to delete non-existent bond %s\n", ifname);
res = -ENODEV;
goto out_unlock;
}
/* Always return either count or an error. If you return 0, you'll
* get called forever, which is bad.
*/
return res;

err_no_cmd:
pr_err(DRV_NAME ": no command found in bonding_masters."
" Use +ifname or -ifname.\n");
return -EPERM;

out_unlock:
rtnl_unlock();

/* Always return either count or an error. If you return 0, you'll
* get called forever, which is bad.
*/
out:
return res;
}

/* class attribute for bond_masters file. This ends up in /sys/class/net */
static CLASS_ATTR(bonding_masters, S_IWUSR | S_IRUGO,
bonding_show_bonds, bonding_store_bonds);
Expand Down Expand Up @@ -233,29 +237,16 @@ static ssize_t bonding_store_slaves(struct device *d,

/* Got a slave name in ifname. Is it already in the list? */
found = 0;
read_lock(&bond->lock);
bond_for_each_slave(bond, slave, i)
if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
pr_err(DRV_NAME
": %s: Interface %s is already enslaved!\n",
bond->dev->name, ifname);
ret = -EPERM;
read_unlock(&bond->lock);
goto out;
}

read_unlock(&bond->lock);
pr_info(DRV_NAME ": %s: Adding slave %s.\n",
bond->dev->name, ifname);
dev = dev_get_by_name(&init_net, ifname);
/* FIXME: get netns from sysfs object */
dev = __dev_get_by_name(&init_net, ifname);
if (!dev) {
pr_info(DRV_NAME
": %s: Interface %s does not exist!\n",
bond->dev->name, ifname);
ret = -EPERM;
ret = -ENODEV;
goto out;
} else
dev_put(dev);
}

if (dev->flags & IFF_UP) {
pr_err(DRV_NAME
Expand All @@ -265,6 +256,22 @@ static ssize_t bonding_store_slaves(struct device *d,
ret = -EPERM;
goto out;
}

read_lock(&bond->lock);
bond_for_each_slave(bond, slave, i)
if (slave->dev == dev) {
pr_err(DRV_NAME
": %s: Interface %s is already enslaved!\n",
bond->dev->name, ifname);
ret = -EPERM;
read_unlock(&bond->lock);
goto out;
}
read_unlock(&bond->lock);

pr_info(DRV_NAME ": %s: Adding slave %s.\n",
bond->dev->name, ifname);

/* If this is the first slave, then we need to set
the master's hardware address to be the same as the
slave's. */
Expand Down

0 comments on commit 14f16e7

Please sign in to comment.