From 2901ce199c8f23050613ed44bc58e341d9a83f77 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 13 Oct 2013 05:07:06 +0200 Subject: Reference module as long as an interface exists --- fastd.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/fastd.c b/fastd.c index 55d2a25..505bba5 100644 --- a/fastd.c +++ b/fastd.c @@ -104,7 +104,7 @@ static int fastd_nl_event(struct notifier_block *nb, list_for_each_entry_rcu(entry, &fastd_list, list) { if (entry->owner == n->portid) { - ACCESS_ONCE(entry->owner) = 0; + entry->owner = 0; queue_work(fastd_workqueue, &entry->destroy_work); } @@ -157,10 +157,15 @@ static const struct ethtool_ops fastd_ethtool_ops = { }; +static void fastd_netdev_free(struct net_device *dev) { + free_netdev(dev); + module_put(THIS_MODULE); +} + static void fastd_netdev_setup(struct net_device *dev) { dev->ethtool_ops = &fastd_ethtool_ops; - dev->destructor = free_netdev; + dev->destructor = fastd_netdev_free; } static void fastd_netdev_init(struct net_device *dev) @@ -225,10 +230,15 @@ static int fastd_cmd_create(struct sk_buff *skb, struct genl_info *info) if (info->attrs[FASTD_A_IFNAME]) name = nla_data(info->attrs[FASTD_A_IFNAME]); + if (!try_module_get(THIS_MODULE)) + return -ENOENT; + dev = alloc_netdev(sizeof(struct fastd_struct), name, fastd_netdev_setup); - if (!dev) - return -ENOMEM; + if (!dev) { + err = -ENOMEM; + goto err_module_put; + } dev_net_set(dev, net); @@ -255,6 +265,10 @@ static int fastd_cmd_create(struct sk_buff *skb, struct genl_info *info) err_free_dev: free_netdev(dev); + +err_module_put: + module_put(THIS_MODULE); + return err; } -- cgit v1.2.3