From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Htx0LDjy6T0ZD3lMBiQy0fXAwbXbhnsbVoYgfqzok8Q=; b=TMYP30jq+VepZRJxej2FYxECFs8j1u5Pst7NOxt9SDy9xG1UhwcunOGJdQY3g6363G 3QWnA0+x9Ztd0uafvlcdHpDhWcYHHnX6zRv9zcYyykW5GO0znt8Qwq6Gs4KYmkpv86Vx HMESEL+5xib2ZCiEOt1Jl14L+FoHHQY6gbd1Y= From: Nikolay Aleksandrov Date: Mon, 23 Jul 2018 11:16:58 +0300 Message-Id: <20180723081659.21986-2-nikolay@cumulusnetworks.com> In-Reply-To: <20180723081659.21986-1-nikolay@cumulusnetworks.com> References: <20180723081659.21986-1-nikolay@cumulusnetworks.com> Subject: [Bridge] [PATCH 1/2 net-next v3] net: bridge: add support for raw sysfs port options List-Id: Linux Ethernet Bridging List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: netdev@vger.kernel.org Cc: Nikolay Aleksandrov , roopa@cumulusnetworks.com, bridge@lists.linux-foundation.org, wkok@cumulusnetworks.com, anuradhak@cumulusnetworks.com, davem@davemloft.net This patch adds a new alternative store callback for port sysfs options which takes a raw value (buf) and can use it directly. It is needed for the backup port sysfs support since we have to pass the device by its name. Signed-off-by: Nikolay Aleksandrov --- There are a few checkpatch warnings here because of the old code, I've noted them in my todo and will send separate patch for simple_strtoul and the function prototypes. v3: no change v2: Use kstrndup/kfree instead of casting the const buf. In order to avoid using GFP_ATOMIC or always allocating I kept the spinlock inside each branch. net/bridge/br_sysfs_if.c | 56 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index ab4c7f8adf68..4ac940067754 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c @@ -25,6 +25,15 @@ struct brport_attribute { struct attribute attr; ssize_t (*show)(struct net_bridge_port *, char *); int (*store)(struct net_bridge_port *, unsigned long); + int (*store_raw)(struct net_bridge_port *, char *); +}; + +#define BRPORT_ATTR_RAW(_name, _mode, _show, _store) \ +const struct brport_attribute brport_attr_##_name = { \ + .attr = {.name = __stringify(_name), \ + .mode = _mode }, \ + .show = _show, \ + .store_raw = _store, \ }; #define BRPORT_ATTR(_name, _mode, _show, _store) \ @@ -269,27 +278,46 @@ static ssize_t brport_store(struct kobject *kobj, struct brport_attribute *brport_attr = to_brport_attr(attr); struct net_bridge_port *p = kobj_to_brport(kobj); ssize_t ret = -EINVAL; - char *endp; unsigned long val; + char *endp; if (!ns_capable(dev_net(p->dev)->user_ns, CAP_NET_ADMIN)) return -EPERM; - val = simple_strtoul(buf, &endp, 0); - if (endp != buf) { - if (!rtnl_trylock()) - return restart_syscall(); - if (p->dev && p->br && brport_attr->store) { - spin_lock_bh(&p->br->lock); - ret = brport_attr->store(p, val); - spin_unlock_bh(&p->br->lock); - if (!ret) { - br_ifinfo_notify(RTM_NEWLINK, NULL, p); - ret = count; - } + if (!rtnl_trylock()) + return restart_syscall(); + + if (!p->dev || !p->br) + goto out_unlock; + + if (brport_attr->store_raw) { + char *buf_copy; + + buf_copy = kstrndup(buf, count, GFP_KERNEL); + if (!buf_copy) { + ret = -ENOMEM; + goto out_unlock; } - rtnl_unlock(); + spin_lock_bh(&p->br->lock); + ret = brport_attr->store_raw(p, buf_copy); + spin_unlock_bh(&p->br->lock); + kfree(buf_copy); + } else if (brport_attr->store) { + val = simple_strtoul(buf, &endp, 0); + if (endp == buf) + goto out_unlock; + spin_lock_bh(&p->br->lock); + ret = brport_attr->store(p, val); + spin_unlock_bh(&p->br->lock); } + + if (!ret) { + br_ifinfo_notify(RTM_NEWLINK, NULL, p); + ret = count; + } +out_unlock: + rtnl_unlock(); + return ret; } -- 2.11.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nikolay Aleksandrov Subject: [PATCH 1/2 net-next v3] net: bridge: add support for raw sysfs port options Date: Mon, 23 Jul 2018 11:16:58 +0300 Message-ID: <20180723081659.21986-2-nikolay@cumulusnetworks.com> References: <20180723081659.21986-1-nikolay@cumulusnetworks.com> Cc: roopa@cumulusnetworks.com, davem@davemloft.net, anuradhak@cumulusnetworks.com, wkok@cumulusnetworks.com, bridge@lists.linux-foundation.org, stephen@networkplumber.org, makita.toshiaki@lab.ntt.co.jp, Nikolay Aleksandrov To: netdev@vger.kernel.org Return-path: Received: from mail-wr1-f67.google.com ([209.85.221.67]:45290 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387913AbeGWJRT (ORCPT ); Mon, 23 Jul 2018 05:17:19 -0400 Received: by mail-wr1-f67.google.com with SMTP id t13-v6so7533424wrv.12 for ; Mon, 23 Jul 2018 01:17:17 -0700 (PDT) In-Reply-To: <20180723081659.21986-1-nikolay@cumulusnetworks.com> Sender: netdev-owner@vger.kernel.org List-ID: This patch adds a new alternative store callback for port sysfs options which takes a raw value (buf) and can use it directly. It is needed for the backup port sysfs support since we have to pass the device by its name. Signed-off-by: Nikolay Aleksandrov --- There are a few checkpatch warnings here because of the old code, I've noted them in my todo and will send separate patch for simple_strtoul and the function prototypes. v3: no change v2: Use kstrndup/kfree instead of casting the const buf. In order to avoid using GFP_ATOMIC or always allocating I kept the spinlock inside each branch. net/bridge/br_sysfs_if.c | 56 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index ab4c7f8adf68..4ac940067754 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c @@ -25,6 +25,15 @@ struct brport_attribute { struct attribute attr; ssize_t (*show)(struct net_bridge_port *, char *); int (*store)(struct net_bridge_port *, unsigned long); + int (*store_raw)(struct net_bridge_port *, char *); +}; + +#define BRPORT_ATTR_RAW(_name, _mode, _show, _store) \ +const struct brport_attribute brport_attr_##_name = { \ + .attr = {.name = __stringify(_name), \ + .mode = _mode }, \ + .show = _show, \ + .store_raw = _store, \ }; #define BRPORT_ATTR(_name, _mode, _show, _store) \ @@ -269,27 +278,46 @@ static ssize_t brport_store(struct kobject *kobj, struct brport_attribute *brport_attr = to_brport_attr(attr); struct net_bridge_port *p = kobj_to_brport(kobj); ssize_t ret = -EINVAL; - char *endp; unsigned long val; + char *endp; if (!ns_capable(dev_net(p->dev)->user_ns, CAP_NET_ADMIN)) return -EPERM; - val = simple_strtoul(buf, &endp, 0); - if (endp != buf) { - if (!rtnl_trylock()) - return restart_syscall(); - if (p->dev && p->br && brport_attr->store) { - spin_lock_bh(&p->br->lock); - ret = brport_attr->store(p, val); - spin_unlock_bh(&p->br->lock); - if (!ret) { - br_ifinfo_notify(RTM_NEWLINK, NULL, p); - ret = count; - } + if (!rtnl_trylock()) + return restart_syscall(); + + if (!p->dev || !p->br) + goto out_unlock; + + if (brport_attr->store_raw) { + char *buf_copy; + + buf_copy = kstrndup(buf, count, GFP_KERNEL); + if (!buf_copy) { + ret = -ENOMEM; + goto out_unlock; } - rtnl_unlock(); + spin_lock_bh(&p->br->lock); + ret = brport_attr->store_raw(p, buf_copy); + spin_unlock_bh(&p->br->lock); + kfree(buf_copy); + } else if (brport_attr->store) { + val = simple_strtoul(buf, &endp, 0); + if (endp == buf) + goto out_unlock; + spin_lock_bh(&p->br->lock); + ret = brport_attr->store(p, val); + spin_unlock_bh(&p->br->lock); } + + if (!ret) { + br_ifinfo_notify(RTM_NEWLINK, NULL, p); + ret = count; + } +out_unlock: + rtnl_unlock(); + return ret; } -- 2.11.0