summaryrefslogtreecommitdiff
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-05-03 13:57:20 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-06-03 08:22:08 +0200
commit7811cd97e1f83300ea90bb3ac9a38e2f6f9ae3b1 (patch)
tree22cef3d0bff440563596d740172089df9896677b /drivers/net/wireless
parent3ca5641d581e8630dab67992ee63c91fb5122def (diff)
libertas: register sysfs groups properly
[ Upstream commit 7e79b38fe9a403b065ac5915465f620a8fb3de84 ] The libertas driver was trying to register sysfs groups "by hand" which causes them to be created _after_ the device is initialized and announced to userspace, which causes races and can prevent userspace tools from seeing the sysfs files correctly. Fix this up by using the built-in sysfs_groups pointers in struct net_device which were created for this very reason, fixing the race condition, and properly allowing for any error that might have occured to be handled properly. Cc: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/20210503115736.2104747-54-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/libertas/mesh.c28
1 files changed, 4 insertions, 24 deletions
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
index d0c881dd5846..f1e9cbcfdc16 100644
--- a/drivers/net/wireless/libertas/mesh.c
+++ b/drivers/net/wireless/libertas/mesh.c
@@ -797,19 +797,6 @@ static const struct attribute_group mesh_ie_group = {
.attrs = mesh_ie_attrs,
};
-static void lbs_persist_config_init(struct net_device *dev)
-{
- int ret;
- ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group);
- ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group);
-}
-
-static void lbs_persist_config_remove(struct net_device *dev)
-{
- sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group);
- sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group);
-}
-
/***************************************************************************
* Initializing and starting, stopping mesh
@@ -1021,6 +1008,10 @@ static int lbs_add_mesh(struct lbs_private *priv)
SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
+ mesh_dev->sysfs_groups[0] = &lbs_mesh_attr_group;
+ mesh_dev->sysfs_groups[1] = &boot_opts_group;
+ mesh_dev->sysfs_groups[2] = &mesh_ie_group;
+
/* Register virtual mesh interface */
ret = register_netdev(mesh_dev);
if (ret) {
@@ -1028,19 +1019,10 @@ static int lbs_add_mesh(struct lbs_private *priv)
goto err_free_netdev;
}
- ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
- if (ret)
- goto err_unregister;
-
- lbs_persist_config_init(mesh_dev);
-
/* Everything successful */
ret = 0;
goto done;
-err_unregister:
- unregister_netdev(mesh_dev);
-
err_free_netdev:
free_netdev(mesh_dev);
@@ -1063,8 +1045,6 @@ void lbs_remove_mesh(struct lbs_private *priv)
lbs_deb_enter(LBS_DEB_MESH);
netif_stop_queue(mesh_dev);
netif_carrier_off(mesh_dev);
- sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
- lbs_persist_config_remove(mesh_dev);
unregister_netdev(mesh_dev);
priv->mesh_dev = NULL;
kfree(mesh_dev->ieee80211_ptr);