summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2013-10-13 05:07:06 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2013-10-13 05:07:06 +0200
commit2901ce199c8f23050613ed44bc58e341d9a83f77 (patch)
tree63300ebdefe2c7413d53a81844169ee42caf591f
parent163725e01504c62752aa270523327d73e241517d (diff)
downloadmodfastd-2901ce199c8f23050613ed44bc58e341d9a83f77.tar
modfastd-2901ce199c8f23050613ed44bc58e341d9a83f77.zip
Reference module as long as an interface exists
-rw-r--r--fastd.c22
1 files 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;
}