]> Pileus Git - ~andy/linux/blobdiff - drivers/net/bonding/bond_main.c
bonding: fix device name allocation error
[~andy/linux] / drivers / net / bonding / bond_main.c
index 17a461152d39884157e5e138c71b7ed236fc5427..07b9d1f65b6628c52dbc08e5306593928c181706 100644 (file)
@@ -1336,6 +1336,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                goto err_undo_flags;
        }
 
+       if (slave_dev->get_stats == NULL) {
+               printk(KERN_NOTICE DRV_NAME
+                       ": %s: the driver for slave device %s does not provide "
+                       "get_stats function, network statistics will be "
+                       "inaccurate.\n", bond_dev->name, slave_dev->name);
+       }
+
        new_slave = kmalloc(sizeof(struct slave), GFP_KERNEL);
        if (!new_slave) {
                res = -ENOMEM;
@@ -3605,33 +3612,35 @@ static struct net_device_stats *bond_get_stats(struct net_device *bond_dev)
        read_lock_bh(&bond->lock);
 
        bond_for_each_slave(bond, slave, i) {
-               sstats = slave->dev->get_stats(slave->dev);
-
-               stats->rx_packets += sstats->rx_packets;
-               stats->rx_bytes += sstats->rx_bytes;
-               stats->rx_errors += sstats->rx_errors;
-               stats->rx_dropped += sstats->rx_dropped;
-
-               stats->tx_packets += sstats->tx_packets;
-               stats->tx_bytes += sstats->tx_bytes;
-               stats->tx_errors += sstats->tx_errors;
-               stats->tx_dropped += sstats->tx_dropped;
-
-               stats->multicast += sstats->multicast;
-               stats->collisions += sstats->collisions;
-
-               stats->rx_length_errors += sstats->rx_length_errors;
-               stats->rx_over_errors += sstats->rx_over_errors;
-               stats->rx_crc_errors += sstats->rx_crc_errors;
-               stats->rx_frame_errors += sstats->rx_frame_errors;
-               stats->rx_fifo_errors += sstats->rx_fifo_errors;
-               stats->rx_missed_errors += sstats->rx_missed_errors;
-
-               stats->tx_aborted_errors += sstats->tx_aborted_errors;
-               stats->tx_carrier_errors += sstats->tx_carrier_errors;
-               stats->tx_fifo_errors += sstats->tx_fifo_errors;
-               stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors;
-               stats->tx_window_errors += sstats->tx_window_errors;
+               if (slave->dev->get_stats) {
+                       sstats = slave->dev->get_stats(slave->dev);
+
+                       stats->rx_packets += sstats->rx_packets;
+                       stats->rx_bytes += sstats->rx_bytes;
+                       stats->rx_errors += sstats->rx_errors;
+                       stats->rx_dropped += sstats->rx_dropped;
+
+                       stats->tx_packets += sstats->tx_packets;
+                       stats->tx_bytes += sstats->tx_bytes;
+                       stats->tx_errors += sstats->tx_errors;
+                       stats->tx_dropped += sstats->tx_dropped;
+
+                       stats->multicast += sstats->multicast;
+                       stats->collisions += sstats->collisions;
+
+                       stats->rx_length_errors += sstats->rx_length_errors;
+                       stats->rx_over_errors += sstats->rx_over_errors;
+                       stats->rx_crc_errors += sstats->rx_crc_errors;
+                       stats->rx_frame_errors += sstats->rx_frame_errors;
+                       stats->rx_fifo_errors += sstats->rx_fifo_errors;
+                       stats->rx_missed_errors += sstats->rx_missed_errors;
+
+                       stats->tx_aborted_errors += sstats->tx_aborted_errors;
+                       stats->tx_carrier_errors += sstats->tx_carrier_errors;
+                       stats->tx_fifo_errors += sstats->tx_fifo_errors;
+                       stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors;
+                       stats->tx_window_errors += sstats->tx_window_errors;
+               }
        }
 
        read_unlock_bh(&bond->lock);
@@ -3675,7 +3684,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
                        mii->val_out = 0;
                        read_lock_bh(&bond->lock);
                        read_lock(&bond->curr_slave_lock);
-                       if (bond->curr_active_slave) {
+                       if (netif_carrier_ok(bond->dev)) {
                                mii->val_out = BMSR_LSTATUS;
                        }
                        read_unlock(&bond->curr_slave_lock);
@@ -4695,6 +4704,7 @@ static int bond_check_params(struct bond_params *params)
 static struct lock_class_key bonding_netdev_xmit_lock_key;
 
 /* Create a new bond based on the specified name and bonding parameters.
+ * If name is NULL, obtain a suitable "bond%d" name for us.
  * Caller must NOT hold rtnl_lock; we need to release it here before we
  * set up our sysfs entries.
  */
@@ -4704,7 +4714,8 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
        int res;
 
        rtnl_lock();
-       bond_dev = alloc_netdev(sizeof(struct bonding), name, ether_setup);
+       bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
+                               ether_setup);
        if (!bond_dev) {
                printk(KERN_ERR DRV_NAME
                       ": %s: eek! can't alloc netdev!\n",
@@ -4713,6 +4724,12 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
                goto out_rtnl;
        }
 
+       if (!name) {
+               res = dev_alloc_name(bond_dev, "bond%d");
+               if (res < 0)
+                       goto out_netdev;
+       }
+
        /* bond_init() must be called after dev_alloc_name() (for the
         * /proc files), but before register_netdevice(), because we
         * need to set function pointers.
@@ -4754,7 +4771,6 @@ static int __init bonding_init(void)
 {
        int i;
        int res;
-       char new_bond_name[8];  /* Enough room for 999 bonds at init. */
 
        printk(KERN_INFO "%s", version);
 
@@ -4767,8 +4783,7 @@ static int __init bonding_init(void)
        bond_create_proc_dir();
 #endif
        for (i = 0; i < max_bonds; i++) {
-               sprintf(new_bond_name, "bond%d",i);
-               res = bond_create(new_bond_name,&bonding_defaults, NULL);
+               res = bond_create(NULL, &bonding_defaults, NULL);
                if (res)
                        goto err;
        }