Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libertas: register sysfs groups properly

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>

+4 -24
+4 -24
drivers/net/wireless/marvell/libertas/mesh.c
··· 801 801 .attrs = mesh_ie_attrs, 802 802 }; 803 803 804 - static void lbs_persist_config_init(struct net_device *dev) 805 - { 806 - int ret; 807 - ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group); 808 - ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group); 809 - } 810 - 811 - static void lbs_persist_config_remove(struct net_device *dev) 812 - { 813 - sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group); 814 - sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group); 815 - } 816 - 817 804 818 805 /*************************************************************************** 819 806 * Initializing and starting, stopping mesh ··· 996 1009 SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); 997 1010 998 1011 mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST; 1012 + mesh_dev->sysfs_groups[0] = &lbs_mesh_attr_group; 1013 + mesh_dev->sysfs_groups[1] = &boot_opts_group; 1014 + mesh_dev->sysfs_groups[2] = &mesh_ie_group; 1015 + 999 1016 /* Register virtual mesh interface */ 1000 1017 ret = register_netdev(mesh_dev); 1001 1018 if (ret) { ··· 1007 1016 goto err_free_netdev; 1008 1017 } 1009 1018 1010 - ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); 1011 - if (ret) 1012 - goto err_unregister; 1013 - 1014 - lbs_persist_config_init(mesh_dev); 1015 - 1016 1019 /* Everything successful */ 1017 1020 ret = 0; 1018 1021 goto done; 1019 - 1020 - err_unregister: 1021 - unregister_netdev(mesh_dev); 1022 1022 1023 1023 err_free_netdev: 1024 1024 free_netdev(mesh_dev); ··· 1031 1049 1032 1050 netif_stop_queue(mesh_dev); 1033 1051 netif_carrier_off(mesh_dev); 1034 - sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); 1035 - lbs_persist_config_remove(mesh_dev); 1036 1052 unregister_netdev(mesh_dev); 1037 1053 priv->mesh_dev = NULL; 1038 1054 kfree(mesh_dev->ieee80211_ptr);