From patchwork Fri Oct 18 15:43:35 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 284635 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id BCF0D2C00C5 for ; Sat, 19 Oct 2013 02:43:54 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756492Ab3JRPnu (ORCPT ); Fri, 18 Oct 2013 11:43:50 -0400 Received: from mail-ea0-f169.google.com ([209.85.215.169]:45707 "EHLO mail-ea0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756464Ab3JRPnq (ORCPT ); Fri, 18 Oct 2013 11:43:46 -0400 Received: by mail-ea0-f169.google.com with SMTP id k11so2103107eaj.14 for ; Fri, 18 Oct 2013 08:43:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Wq92S/ZKeIGPzzvbTnY/MnwKMqk6SbDaT6VROQCc0i0=; b=QChY4HzE5abq1LLY2z7z1Y97UbgoMPWdAVHyDqWFihxr0o3ej9MmbcVlc4CJejJZNG cSiNBerJqyKHNdSMne7uJiuD2FvPJxyyLcR713vxcsVn5tN3mwsBZGk1AHjOj58PwVjX 7onDp4SqLhsyc20e1ZajXwzY5TRbvQyIgOE8YxAdlE6zB8QxTF414FTRDv9ZzIWrAqVN 1yR6CspZyBi2/dRfMjyWPRGH3KX33Zm/ZcyEwrKEfHu6KTw4ImwnlvG3U92VUboDXcTq VoOtAYx46FDX3aKFRFt5Nnsg0Af5sZsFyoRPOxWL6WVWG9ETxnYtq1AVsM3Q1JUswcu6 7bKA== X-Gm-Message-State: ALoCoQlVDgmHu4fUowx0MQScde6ivS/E3KW3hLgLDlvb0+XBrdwzk/3qake+6Nmv4AFS14Dg5AtU X-Received: by 10.15.67.131 with SMTP id u3mr5457091eex.34.1382111025367; Fri, 18 Oct 2013 08:43:45 -0700 (PDT) Received: from localhost (sun-0.pirko.cz. [84.16.102.25]) by mx.google.com with ESMTPSA id i1sm6046189eeg.0.2013.10.18.08.43.44 for (version=TLSv1.2 cipher=AES128-GCM-SHA256 bits=128/128); Fri, 18 Oct 2013 08:43:45 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, fubar@us.ibm.com, vfalico@redhat.com, andy@greyhouse.net, stephen@networkplumber.org, vyasevic@redhat.com Subject: [patch net-next 3/7] bonding: move active_slave setting into separate function Date: Fri, 18 Oct 2013 17:43:35 +0200 Message-Id: <1382111019-1102-4-git-send-email-jiri@resnulli.us> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1382111019-1102-1-git-send-email-jiri@resnulli.us> References: <1382111019-1102-1-git-send-email-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Do a bit of refactoring on the way. Signed-off-by: Jiri Pirko --- drivers/net/bonding/bond_options.c | 69 +++++++++++++++++++++++++++++++++++ drivers/net/bonding/bond_sysfs.c | 74 +++++++------------------------------- drivers/net/bonding/bonding.h | 1 + 3 files changed, 83 insertions(+), 61 deletions(-) diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 294b766..09af5d1 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -12,6 +12,9 @@ #include #include +#include +#include +#include #include "bonding.h" static bool bond_mode_is_valid(int mode) @@ -53,3 +56,69 @@ int bond_option_mode_set(struct bonding *bond, int mode) bond->params.mode = mode; return 0; } + +int bond_option_active_slave_set(struct bonding *bond, + struct net_device *slave_dev) +{ + int ret = 0; + + if (slave_dev) { + if (!netif_is_bond_slave(slave_dev)) { + pr_err("Device %s is not bonding slave.\n", + slave_dev->name); + return -EINVAL; + } + + if (bond->dev != netdev_master_upper_dev_get(slave_dev)) { + pr_err("%s: Device %s is not our slave.\n", + bond->dev->name, slave_dev->name); + return -EINVAL; + } + } + + if (!USES_PRIMARY(bond->params.mode)) { + pr_err("%s: Unable to change active slave; %s is in mode %d\n", + bond->dev->name, bond->dev->name, bond->params.mode); + return -EINVAL; + } + + block_netpoll_tx(); + read_lock(&bond->lock); + write_lock_bh(&bond->curr_slave_lock); + + /* check to see if we are clearing active */ + if (!slave_dev) { + pr_info("%s: Clearing current active slave.\n", + bond->dev->name); + rcu_assign_pointer(bond->curr_active_slave, NULL); + bond_select_active_slave(bond); + } else { + struct slave *old_active = bond->curr_active_slave; + struct slave *new_active = bond_slave_get_rtnl(slave_dev); + + BUG_ON(!new_active); + + if (new_active == old_active) { + /* do nothing */ + pr_info("%s: %s is already the current active slave.\n", + bond->dev->name, new_active->dev->name); + } else { + if (old_active && (new_active->link == BOND_LINK_UP) && + IS_UP(new_active->dev)) { + pr_info("%s: Setting %s as active slave.\n", + bond->dev->name, new_active->dev->name); + bond_change_active_slave(bond, new_active); + } else { + pr_err("%s: Could not set %s as active slave; either %s is down or the link is down.\n", + bond->dev->name, new_active->dev->name, + new_active->dev->name); + ret = -EINVAL; + } + } + } + + write_unlock_bh(&bond->curr_slave_lock); + read_unlock(&bond->lock); + unblock_netpoll_tx(); + return ret; +} diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index c234cec..abd2600 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1235,81 +1235,33 @@ static ssize_t bonding_store_active_slave(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct slave *slave, *old_active, *new_active; + int ret; struct bonding *bond = to_bond(d); - struct list_head *iter; char ifname[IFNAMSIZ]; + struct net_device *dev; if (!rtnl_trylock()) return restart_syscall(); - old_active = new_active = NULL; - block_netpoll_tx(); - read_lock(&bond->lock); - write_lock_bh(&bond->curr_slave_lock); - - if (!USES_PRIMARY(bond->params.mode)) { - pr_info("%s: Unable to change active slave; %s is in mode %d\n", - bond->dev->name, bond->dev->name, bond->params.mode); - goto out; - } - sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ - - /* check to see if we are clearing active */ if (!strlen(ifname) || buf[0] == '\n') { - pr_info("%s: Clearing current active slave.\n", - bond->dev->name); - rcu_assign_pointer(bond->curr_active_slave, NULL); - bond_select_active_slave(bond); - goto out; - } - - bond_for_each_slave(bond, slave, iter) { - if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { - old_active = bond->curr_active_slave; - new_active = slave; - if (new_active == old_active) { - /* do nothing */ - pr_info("%s: %s is already the current" - " active slave.\n", - bond->dev->name, - slave->dev->name); - goto out; - } else { - if ((new_active) && - (old_active) && - (new_active->link == BOND_LINK_UP) && - IS_UP(new_active->dev)) { - pr_info("%s: Setting %s as active" - " slave.\n", - bond->dev->name, - slave->dev->name); - bond_change_active_slave(bond, - new_active); - } else { - pr_info("%s: Could not set %s as" - " active slave; either %s is" - " down or the link is down.\n", - bond->dev->name, - slave->dev->name, - slave->dev->name); - } - goto out; - } + dev = NULL; + } else { + dev = __dev_get_by_name(dev_net(bond->dev), ifname); + if (!dev) { + ret = -ENODEV; + goto out; } } - pr_info("%s: Unable to set %.*s as active slave.\n", - bond->dev->name, (int)strlen(buf) - 1, buf); - out: - write_unlock_bh(&bond->curr_slave_lock); - read_unlock(&bond->lock); - unblock_netpoll_tx(); + ret = bond_option_active_slave_set(bond, dev); + if (!ret) + ret = count; + out: rtnl_unlock(); - return count; + return ret; } static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 7446849..686759d 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -427,6 +427,7 @@ unsigned int bond_get_num_tx_queues(void); int bond_netlink_init(void); void bond_netlink_fini(void); int bond_option_mode_set(struct bonding *bond, int mode); +int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev); struct bond_net { struct net * net; /* Associated network namespace */