Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ece95f7fefe3afae19e641e1b3f5e64b00d5b948
Commit:     ece95f7fefe3afae19e641e1b3f5e64b00d5b948
Parent:     3b96c858fcb27120fcba222366180c3293393ccf
Author:     Jay Vosburgh <[EMAIL PROTECTED]>
AuthorDate: Thu Jan 17 16:25:01 2008 -0800
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Fri Jan 18 14:38:38 2008 -0500

    bonding: Fix up parameter parsing
    
        A recent change to add an additional hash policy modified
    bond_parse_parm, but it now does not correctly match parameters passed in
    via sysfs.
    
        Rewrote bond_parse_parm to handle (a) parameter matches that
    are substrings of one another and (b) user input with whitespace (e.g.,
    sysfs input often has a trailing newline).
    
    Signed-off-by: Jay Vosburgh <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/net/bonding/bond_main.c  |   23 ++++++++++++++++-------
 drivers/net/bonding/bond_sysfs.c |    8 ++++----
 drivers/net/bonding/bonding.h    |    4 +++-
 3 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 3ede0a2..379c5d8 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4540,18 +4540,27 @@ static void bond_free_all(void)
 
 /*
  * Convert string input module parms.  Accept either the
- * number of the mode or its string name.
+ * number of the mode or its string name.  A bit complicated because
+ * some mode names are substrings of other names, and calls from sysfs
+ * may have whitespace in the name (trailing newlines, for example).
  */
-int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
+int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl)
 {
-       int i;
+       int mode = -1, i, rv;
+       char modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };
+
+       rv = sscanf(buf, "%d", &mode);
+       if (!rv) {
+               rv = sscanf(buf, "%20s", modestr);
+               if (!rv)
+                       return -1;
+       }
 
        for (i = 0; tbl[i].modename; i++) {
-               if ((isdigit(*mode_arg) &&
-                    tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) ||
-                   (strcmp(mode_arg, tbl[i].modename) == 0)) {
+               if (mode == tbl[i].mode)
+                       return tbl[i].mode;
+               if (strcmp(modestr, tbl[i].modename) == 0)
                        return tbl[i].mode;
-               }
        }
 
        return -1;
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 28a2d80..bff4f2b 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -423,7 +423,7 @@ static ssize_t bonding_store_mode(struct device *d,
                goto out;
        }
 
-       new_value = bond_parse_parm((char *)buf, bond_mode_tbl);
+       new_value = bond_parse_parm(buf, bond_mode_tbl);
        if (new_value < 0)  {
                printk(KERN_ERR DRV_NAME
                       ": %s: Ignoring invalid mode value %.*s.\n",
@@ -478,7 +478,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
                goto out;
        }
 
-       new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl);
+       new_value = bond_parse_parm(buf, xmit_hashtype_tbl);
        if (new_value < 0)  {
                printk(KERN_ERR DRV_NAME
                       ": %s: Ignoring invalid xmit hash policy value %.*s.\n",
@@ -518,7 +518,7 @@ static ssize_t bonding_store_arp_validate(struct device *d,
        int new_value;
        struct bonding *bond = to_bond(d);
 
-       new_value = bond_parse_parm((char *)buf, arp_validate_tbl);
+       new_value = bond_parse_parm(buf, arp_validate_tbl);
        if (new_value < 0) {
                printk(KERN_ERR DRV_NAME
                       ": %s: Ignoring invalid arp_validate value %s\n",
@@ -941,7 +941,7 @@ static ssize_t bonding_store_lacp(struct device *d,
                goto out;
        }
 
-       new_value = bond_parse_parm((char *)buf, bond_lacp_tbl);
+       new_value = bond_parse_parm(buf, bond_lacp_tbl);
 
        if ((new_value == 1) || (new_value == 0)) {
                bond->params.lacp_fast = new_value;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index e1e4734..6d83be4 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -141,6 +141,8 @@ struct bond_parm_tbl {
        int mode;
 };
 
+#define BOND_MAX_MODENAME_LEN 20
+
 struct vlan_entry {
        struct list_head vlan_list;
        __be32 vlan_ip;
@@ -314,7 +316,7 @@ void bond_mii_monitor(struct work_struct *);
 void bond_loadbalance_arp_mon(struct work_struct *);
 void bond_activebackup_arp_mon(struct work_struct *);
 void bond_set_mode_ops(struct bonding *bond, int mode);
-int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
+int bond_parse_parm(const char *mode_arg, struct bond_parm_tbl *tbl);
 void bond_select_active_slave(struct bonding *bond);
 void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
 void bond_register_arp(struct bonding *);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to