From: Gao Feng <gfree.w...@foxmail.com> The batman-adv allocates some resources in its ndo_init func, and free them in its destructor func. Then there is one memleak that some errors happen after register_netdevice invokes the ndo_init callback. Because the destructor would not be invoked to free the resources.
Now create one new func batadv_destructor_free to free the mem in the destructor, and add ndo_uninit func also invokes it when fail to register the batman-adv device. It's not only free all resources, but also follow the original desgin that the resources are freed in the destructor normally after register the device successfully. Signed-off-by: Gao Feng <gfree.w...@foxmail.com> --- net/batman-adv/soft-interface.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index d042c99..626cbf6 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -878,6 +878,19 @@ static int batadv_softif_init_late(struct net_device *dev) return ret; } +static void batadv_destructor_free(struct net_device *dev) +{ + batadv_debugfs_del_meshif(dev); + batadv_mesh_free(dev); +} + +static void batadv_softif_uninit(struct net_device *dev) +{ + /* dev is not registered, perform the free instead of destructor */ + if (dev->reg_state == NETREG_UNINITIALIZED) + batadv_destructor_free(dev); +} + /** * batadv_softif_slave_add - Add a slave interface to a batadv_soft_interface * @dev: batadv_soft_interface used as master interface @@ -933,6 +946,7 @@ static int batadv_softif_slave_del(struct net_device *dev, static const struct net_device_ops batadv_netdev_ops = { .ndo_init = batadv_softif_init_late, + .ndo_uninit = batadv_softif_uninit, .ndo_open = batadv_interface_open, .ndo_stop = batadv_interface_release, .ndo_get_stats = batadv_interface_stats, @@ -953,9 +967,7 @@ static int batadv_softif_slave_del(struct net_device *dev, */ static void batadv_softif_free(struct net_device *dev) { - batadv_debugfs_del_meshif(dev); - batadv_mesh_free(dev); - + batadv_destructor_free(dev); /* some scheduled RCU callbacks need the bat_priv struct to accomplish * their tasks. Wait for them all to be finished before freeing the * netdev and its private data (bat_priv) -- 1.9.1