bonding: convert queue_id to use the new option API

This patch adds the necessary changes so queue_id would use
the new bonding option API. Also move it to its own set function in
bond_options.c and fix some style errors.

Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Nikolay Aleksandrov 2014-01-22 14:53:36 +01:00 committed by David S. Miller
parent d1fbd3ed93
commit 24089ba102
3 changed files with 77 additions and 61 deletions

View File

@ -254,6 +254,13 @@ static struct bond_option bond_opts[] = {
BIT(BOND_MODE_ALB)), BIT(BOND_MODE_ALB)),
.set = bond_option_active_slave_set .set = bond_option_active_slave_set
}, },
[BOND_OPT_QUEUE_ID] = {
.id = BOND_OPT_QUEUE_ID,
.name = "queue_id",
.desc = "Set queue id of a slave",
.flags = BOND_OPTFLAG_RAWVAL,
.set = bond_option_queue_id_set
},
{ } { }
}; };
@ -1130,3 +1137,66 @@ int bond_option_ad_select_set(struct bonding *bond,
return 0; return 0;
} }
int bond_option_queue_id_set(struct bonding *bond,
struct bond_opt_value *newval)
{
struct slave *slave, *update_slave;
struct net_device *sdev;
struct list_head *iter;
char *delim;
int ret = 0;
u16 qid;
/* delim will point to queue id if successful */
delim = strchr(newval->string, ':');
if (!delim)
goto err_no_cmd;
/* Terminate string that points to device name and bump it
* up one, so we can read the queue id there.
*/
*delim = '\0';
if (sscanf(++delim, "%hd\n", &qid) != 1)
goto err_no_cmd;
/* Check buffer length, valid ifname and queue id */
if (strlen(newval->string) > IFNAMSIZ ||
!dev_valid_name(newval->string) ||
qid > bond->dev->real_num_tx_queues)
goto err_no_cmd;
/* Get the pointer to that interface if it exists */
sdev = __dev_get_by_name(dev_net(bond->dev), newval->string);
if (!sdev)
goto err_no_cmd;
/* Search for thes slave and check for duplicate qids */
update_slave = NULL;
bond_for_each_slave(bond, slave, iter) {
if (sdev == slave->dev)
/* We don't need to check the matching
* slave for dups, since we're overwriting it
*/
update_slave = slave;
else if (qid && qid == slave->queue_id) {
goto err_no_cmd;
}
}
if (!update_slave)
goto err_no_cmd;
/* Actually set the qids for the slave */
update_slave->queue_id = qid;
out:
return ret;
err_no_cmd:
pr_info("invalid input for queue_id set for %s.\n",
bond->dev->name);
ret = -EPERM;
goto out;
}

View File

@ -57,6 +57,7 @@ enum {
BOND_OPT_PRIMARY_RESELECT, BOND_OPT_PRIMARY_RESELECT,
BOND_OPT_USE_CARRIER, BOND_OPT_USE_CARRIER,
BOND_OPT_ACTIVE_SLAVE, BOND_OPT_ACTIVE_SLAVE,
BOND_OPT_QUEUE_ID,
BOND_OPT_LAST BOND_OPT_LAST
}; };
@ -153,4 +154,6 @@ int bond_option_use_carrier_set(struct bonding *bond,
struct bond_opt_value *newval); struct bond_opt_value *newval);
int bond_option_active_slave_set(struct bonding *bond, int bond_option_active_slave_set(struct bonding *bond,
struct bond_opt_value *newval); struct bond_opt_value *newval);
int bond_option_queue_id_set(struct bonding *bond,
struct bond_opt_value *newval);
#endif /* _BOND_OPTIONS_H */ #endif /* _BOND_OPTIONS_H */

View File

@ -985,72 +985,15 @@ static ssize_t bonding_store_queue_id(struct device *d,
struct device_attribute *attr, struct device_attribute *attr,
const char *buffer, size_t count) const char *buffer, size_t count)
{ {
struct slave *slave, *update_slave;
struct bonding *bond = to_bond(d); struct bonding *bond = to_bond(d);
struct list_head *iter; int ret;
u16 qid;
int ret = count;
char *delim;
struct net_device *sdev = NULL;
if (!rtnl_trylock()) ret = bond_opt_tryset_rtnl(bond, BOND_OPT_QUEUE_ID, (char *)buffer);
return restart_syscall(); if (!ret)
ret = count;
/* delim will point to queue id if successful */
delim = strchr(buffer, ':');
if (!delim)
goto err_no_cmd;
/*
* Terminate string that points to device name and bump it
* up one, so we can read the queue id there.
*/
*delim = '\0';
if (sscanf(++delim, "%hd\n", &qid) != 1)
goto err_no_cmd;
/* Check buffer length, valid ifname and queue id */
if (strlen(buffer) > IFNAMSIZ ||
!dev_valid_name(buffer) ||
qid > bond->dev->real_num_tx_queues)
goto err_no_cmd;
/* Get the pointer to that interface if it exists */
sdev = __dev_get_by_name(dev_net(bond->dev), buffer);
if (!sdev)
goto err_no_cmd;
/* Search for thes slave and check for duplicate qids */
update_slave = NULL;
bond_for_each_slave(bond, slave, iter) {
if (sdev == slave->dev)
/*
* We don't need to check the matching
* slave for dups, since we're overwriting it
*/
update_slave = slave;
else if (qid && qid == slave->queue_id) {
goto err_no_cmd;
}
}
if (!update_slave)
goto err_no_cmd;
/* Actually set the qids for the slave */
update_slave->queue_id = qid;
out:
rtnl_unlock();
return ret; return ret;
err_no_cmd:
pr_info("invalid input for queue_id set for %s.\n",
bond->dev->name);
ret = -EPERM;
goto out;
} }
static DEVICE_ATTR(queue_id, S_IRUGO | S_IWUSR, bonding_show_queue_id, static DEVICE_ATTR(queue_id, S_IRUGO | S_IWUSR, bonding_show_queue_id,
bonding_store_queue_id); bonding_store_queue_id);