mac80211: station state transition error handling
In the future, when we start notifying drivers, state transitions could potentially fail. To make it easier to distinguish between programming bugs and driver failures: * rename sta_info_move_state() to sta_info_pre_move_state() which can only be called before the station is inserted (and check this with a new station flag). * rename sta_info_move_state_checked() to just plain sta_info_move_state(), as it will be the regular function that can fail for more than just one reason (bad transition or an error from the driver) This makes the programming model easier -- one of the functions can only be called before insertion and can't fail, the other can fail. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:

committed by
John W. Linville

parent
c037b8367c
commit
83d5cc0124
@@ -403,6 +403,8 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
|
||||
sta_info_hash_add(local, sta);
|
||||
|
||||
list_add(&sta->list, &local->sta_list);
|
||||
|
||||
set_sta_flag(sta, WLAN_STA_INSERTED);
|
||||
} else {
|
||||
sta->dummy = false;
|
||||
}
|
||||
@@ -707,7 +709,7 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
|
||||
return have_buffered;
|
||||
}
|
||||
|
||||
static int __must_check __sta_info_destroy(struct sta_info *sta)
|
||||
int __must_check __sta_info_destroy(struct sta_info *sta)
|
||||
{
|
||||
struct ieee80211_local *local;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
@@ -722,6 +724,8 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
|
||||
local = sta->local;
|
||||
sdata = sta->sdata;
|
||||
|
||||
lockdep_assert_held(&local->sta_mtx);
|
||||
|
||||
/*
|
||||
* Before removing the station from the driver and
|
||||
* rate control, it might still start new aggregation
|
||||
@@ -763,8 +767,13 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||
RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
|
||||
|
||||
while (sta->sta_state > IEEE80211_STA_NONE)
|
||||
sta_info_move_state(sta, sta->sta_state - 1);
|
||||
while (sta->sta_state > IEEE80211_STA_NONE) {
|
||||
int err = sta_info_move_state(sta, sta->sta_state - 1);
|
||||
if (err) {
|
||||
WARN_ON_ONCE(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sta->uploaded) {
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||
@@ -1391,8 +1400,8 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_sta_set_buffered);
|
||||
|
||||
int sta_info_move_state_checked(struct sta_info *sta,
|
||||
enum ieee80211_sta_state new_state)
|
||||
int sta_info_move_state(struct sta_info *sta,
|
||||
enum ieee80211_sta_state new_state)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
|
Reference in New Issue
Block a user