|
@@ -143,8 +143,11 @@ void cfg80211_put_dev(struct cfg80211_registered_device *drv)
|
|
|
int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
|
|
|
char *newname)
|
|
|
{
|
|
|
+ struct cfg80211_registered_device *drv;
|
|
|
int idx, taken = -1, result, digits;
|
|
|
|
|
|
+ mutex_lock(&cfg80211_drv_mutex);
|
|
|
+
|
|
|
/* prohibit calling the thing phy%d when %d is not its number */
|
|
|
sscanf(newname, PHY_NAME "%d%n", &idx, &taken);
|
|
|
if (taken == strlen(newname) && idx != rdev->idx) {
|
|
@@ -156,14 +159,30 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
|
|
|
* deny the name if it is phy<idx> where <idx> is printed
|
|
|
* without leading zeroes. taken == strlen(newname) here
|
|
|
*/
|
|
|
+ result = -EINVAL;
|
|
|
if (taken == strlen(PHY_NAME) + digits)
|
|
|
- return -EINVAL;
|
|
|
+ goto out_unlock;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /* Ignore nop renames */
|
|
|
+ result = 0;
|
|
|
+ if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0)
|
|
|
+ goto out_unlock;
|
|
|
+
|
|
|
+ /* Ensure another device does not already have this name. */
|
|
|
+ list_for_each_entry(drv, &cfg80211_drv_list, list) {
|
|
|
+ result = -EINVAL;
|
|
|
+ if (strcmp(newname, dev_name(&drv->wiphy.dev)) == 0)
|
|
|
+ goto out_unlock;
|
|
|
}
|
|
|
|
|
|
- /* this will check for collisions */
|
|
|
+ /* this will only check for collisions in sysfs
|
|
|
+ * which is not even always compiled in.
|
|
|
+ */
|
|
|
result = device_rename(&rdev->wiphy.dev, newname);
|
|
|
if (result)
|
|
|
- return result;
|
|
|
+ goto out_unlock;
|
|
|
|
|
|
if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
|
|
|
rdev->wiphy.debugfsdir,
|
|
@@ -172,9 +191,13 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
|
|
|
printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n",
|
|
|
newname);
|
|
|
|
|
|
- nl80211_notify_dev_rename(rdev);
|
|
|
+ result = 0;
|
|
|
+out_unlock:
|
|
|
+ mutex_unlock(&cfg80211_drv_mutex);
|
|
|
+ if (result == 0)
|
|
|
+ nl80211_notify_dev_rename(rdev);
|
|
|
|
|
|
- return 0;
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
/* exported functions */
|