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>
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 6f77f12..381de37 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -52,6 +52,7 @@
* @WLAN_STA_SP: Station is in a service period, so don't try to
* reply to other uAPSD trigger frames or PS-Poll.
* @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame.
+ * @WLAN_STA_INSERTED: This station is inserted into the hash table.
*/
enum ieee80211_sta_info_flags {
WLAN_STA_AUTH,
@@ -71,6 +72,7 @@
WLAN_STA_UAPSD,
WLAN_STA_SP,
WLAN_STA_4ADDR_EVENT,
+ WLAN_STA_INSERTED,
};
enum ieee80211_sta_state {
@@ -427,13 +429,17 @@
return test_and_set_bit(flag, &sta->_flags);
}
-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);
-static inline void sta_info_move_state(struct sta_info *sta,
- enum ieee80211_sta_state new_state)
+static inline void sta_info_pre_move_state(struct sta_info *sta,
+ enum ieee80211_sta_state new_state)
{
- int ret = sta_info_move_state_checked(sta, new_state);
+ int ret;
+
+ WARN_ON_ONCE(test_sta_flag(sta, WLAN_STA_INSERTED));
+
+ ret = sta_info_move_state(sta, new_state);
WARN_ON_ONCE(ret);
}
@@ -544,6 +550,7 @@
int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU);
int sta_info_reinsert(struct sta_info *sta);
+int __must_check __sta_info_destroy(struct sta_info *sta);
int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata,
const u8 *addr);
int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata,