diff options
| -rw-r--r-- | net/wireless/core.c | 30 | ||||
| -rw-r--r-- | net/wireless/core.h | 3 | ||||
| -rw-r--r-- | net/wireless/nl80211.c | 28 |
3 files changed, 33 insertions, 28 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c index 17fe39049740..d1f556535f6d 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
| @@ -87,7 +87,7 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx) | |||
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | /* requires cfg80211_mutex to be held! */ | 89 | /* requires cfg80211_mutex to be held! */ |
| 90 | static struct cfg80211_registered_device * | 90 | struct cfg80211_registered_device * |
| 91 | __cfg80211_drv_from_info(struct genl_info *info) | 91 | __cfg80211_drv_from_info(struct genl_info *info) |
| 92 | { | 92 | { |
| 93 | int ifindex; | 93 | int ifindex; |
| @@ -176,13 +176,14 @@ void cfg80211_put_dev(struct cfg80211_registered_device *drv) | |||
| 176 | mutex_unlock(&drv->mtx); | 176 | mutex_unlock(&drv->mtx); |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | /* requires cfg80211_mutex to be held */ | ||
| 179 | int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | 180 | int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, |
| 180 | char *newname) | 181 | char *newname) |
| 181 | { | 182 | { |
| 182 | struct cfg80211_registered_device *drv; | 183 | struct cfg80211_registered_device *drv; |
| 183 | int wiphy_idx, taken = -1, result, digits; | 184 | int wiphy_idx, taken = -1, result, digits; |
| 184 | 185 | ||
| 185 | mutex_lock(&cfg80211_mutex); | 186 | assert_cfg80211_lock(); |
| 186 | 187 | ||
| 187 | /* prohibit calling the thing phy%d when %d is not its number */ | 188 | /* prohibit calling the thing phy%d when %d is not its number */ |
| 188 | sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken); | 189 | sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken); |
| @@ -195,30 +196,23 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
| 195 | * deny the name if it is phy<idx> where <idx> is printed | 196 | * deny the name if it is phy<idx> where <idx> is printed |
| 196 | * without leading zeroes. taken == strlen(newname) here | 197 | * without leading zeroes. taken == strlen(newname) here |
| 197 | */ | 198 | */ |
| 198 | result = -EINVAL; | ||
| 199 | if (taken == strlen(PHY_NAME) + digits) | 199 | if (taken == strlen(PHY_NAME) + digits) |
| 200 | goto out_unlock; | 200 | return -EINVAL; |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | 203 | ||
| 204 | /* Ignore nop renames */ | 204 | /* Ignore nop renames */ |
| 205 | result = 0; | ||
| 206 | if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) | 205 | if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) |
| 207 | goto out_unlock; | 206 | return 0; |
| 208 | 207 | ||
| 209 | /* Ensure another device does not already have this name. */ | 208 | /* Ensure another device does not already have this name. */ |
| 210 | list_for_each_entry(drv, &cfg80211_drv_list, list) { | 209 | list_for_each_entry(drv, &cfg80211_drv_list, list) |
| 211 | result = -EINVAL; | ||
| 212 | if (strcmp(newname, dev_name(&drv->wiphy.dev)) == 0) | 210 | if (strcmp(newname, dev_name(&drv->wiphy.dev)) == 0) |
| 213 | goto out_unlock; | 211 | return -EINVAL; |
| 214 | } | ||
| 215 | 212 | ||
| 216 | /* this will only check for collisions in sysfs | ||
| 217 | * which is not even always compiled in. | ||
| 218 | */ | ||
| 219 | result = device_rename(&rdev->wiphy.dev, newname); | 213 | result = device_rename(&rdev->wiphy.dev, newname); |
| 220 | if (result) | 214 | if (result) |
| 221 | goto out_unlock; | 215 | return result; |
| 222 | 216 | ||
| 223 | if (rdev->wiphy.debugfsdir && | 217 | if (rdev->wiphy.debugfsdir && |
| 224 | !debugfs_rename(rdev->wiphy.debugfsdir->d_parent, | 218 | !debugfs_rename(rdev->wiphy.debugfsdir->d_parent, |
| @@ -228,13 +222,9 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
| 228 | printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n", | 222 | printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n", |
| 229 | newname); | 223 | newname); |
| 230 | 224 | ||
| 231 | result = 0; | 225 | nl80211_notify_dev_rename(rdev); |
| 232 | out_unlock: | ||
| 233 | mutex_unlock(&cfg80211_mutex); | ||
| 234 | if (result == 0) | ||
| 235 | nl80211_notify_dev_rename(rdev); | ||
| 236 | 226 | ||
| 237 | return result; | 227 | return 0; |
| 238 | } | 228 | } |
| 239 | 229 | ||
| 240 | /* exported functions */ | 230 | /* exported functions */ |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 97a6fd8b2b03..d43daa236ef9 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
| @@ -99,6 +99,9 @@ struct cfg80211_internal_bss { | |||
| 99 | struct cfg80211_registered_device *cfg80211_drv_by_wiphy_idx(int wiphy_idx); | 99 | struct cfg80211_registered_device *cfg80211_drv_by_wiphy_idx(int wiphy_idx); |
| 100 | int get_wiphy_idx(struct wiphy *wiphy); | 100 | int get_wiphy_idx(struct wiphy *wiphy); |
| 101 | 101 | ||
| 102 | struct cfg80211_registered_device * | ||
| 103 | __cfg80211_drv_from_info(struct genl_info *info); | ||
| 104 | |||
| 102 | /* | 105 | /* |
| 103 | * This function returns a pointer to the driver | 106 | * This function returns a pointer to the driver |
| 104 | * that the genl_info item that is passed refers to. | 107 | * that the genl_info item that is passed refers to. |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8808431bd581..353e1a4ece83 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -366,16 +366,26 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
| 366 | int result = 0, rem_txq_params = 0; | 366 | int result = 0, rem_txq_params = 0; |
| 367 | struct nlattr *nl_txq_params; | 367 | struct nlattr *nl_txq_params; |
| 368 | 368 | ||
| 369 | rdev = cfg80211_get_dev_from_info(info); | 369 | rtnl_lock(); |
| 370 | if (IS_ERR(rdev)) | 370 | |
| 371 | return PTR_ERR(rdev); | 371 | mutex_lock(&cfg80211_mutex); |
| 372 | |||
| 373 | rdev = __cfg80211_drv_from_info(info); | ||
| 374 | if (IS_ERR(rdev)) { | ||
| 375 | result = PTR_ERR(rdev); | ||
| 376 | goto unlock; | ||
| 377 | } | ||
| 372 | 378 | ||
| 373 | if (info->attrs[NL80211_ATTR_WIPHY_NAME]) { | 379 | mutex_lock(&rdev->mtx); |
| 380 | |||
| 381 | if (info->attrs[NL80211_ATTR_WIPHY_NAME]) | ||
| 374 | result = cfg80211_dev_rename( | 382 | result = cfg80211_dev_rename( |
| 375 | rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); | 383 | rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); |
| 376 | if (result) | 384 | |
| 377 | goto bad_res; | 385 | mutex_unlock(&cfg80211_mutex); |
| 378 | } | 386 | |
| 387 | if (result) | ||
| 388 | goto bad_res; | ||
| 379 | 389 | ||
| 380 | if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) { | 390 | if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) { |
| 381 | struct ieee80211_txq_params txq_params; | 391 | struct ieee80211_txq_params txq_params; |
| @@ -471,7 +481,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
| 471 | 481 | ||
| 472 | 482 | ||
| 473 | bad_res: | 483 | bad_res: |
| 474 | cfg80211_put_dev(rdev); | 484 | mutex_unlock(&rdev->mtx); |
| 485 | unlock: | ||
| 486 | rtnl_unlock(); | ||
| 475 | return result; | 487 | return result; |
| 476 | } | 488 | } |
| 477 | 489 | ||
