Search Linux Wireless

[PATCH 06/12] cfg80211: properly free nontransmitted list on all paths

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Sara Sharon <sara.sharon@xxxxxxxxx>

Free the list inside __cfg80211_unlink_bss and not in
cfg80211_unlink_bss, since not all paths call the later.

Signed-off-by: Sara Sharon <sara.sharon@xxxxxxxxx>
Signed-off-by: Johannes Berg <johannes.berg@xxxxxxxxx>
---
 net/wireless/scan.c | 40 +++++++++++++++++++++++++---------------
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 1e95b46e84e2..1f5535ec4b01 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -152,6 +152,9 @@ static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
 static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev,
 				  struct cfg80211_internal_bss *bss)
 {
+	struct cfg80211_bss *nontrans_bss, *tmp;
+	struct cfg80211_internal_bss *tmp1;
+
 	lockdep_assert_held(&rdev->bss_lock);
 
 	if (!list_empty(&bss->hidden_list)) {
@@ -168,8 +171,26 @@ static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev,
 		list_del_init(&bss->hidden_list);
 	}
 
-	list_del_init(&bss->list);
+	/*
+	 * If the deleted entry is a non-transmitting BSS, just remove it
+	 * from the list.
+	 * if it is the transmitting BSS - free the entire list.
+	 */
+	if (!bss->pub.transmitted_bss &&
+	    !list_empty(&bss->pub.nontrans_list)) {
+		list_for_each_entry_safe(nontrans_bss, tmp,
+					 &bss->pub.nontrans_list,
+					 nontrans_list) {
+			tmp1 = container_of(nontrans_bss,
+					    struct cfg80211_internal_bss, pub);
+			if (__cfg80211_unlink_bss(rdev, tmp1))
+				rdev->bss_generation++;
+		}
+	}
 	list_del_init(&bss->pub.nontrans_list);
+
+	list_del_init(&bss->list);
+
 	rb_erase(&bss->rbn, &rdev->bss_tree);
 	rdev->bss_entries--;
 	WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list),
@@ -1787,8 +1808,7 @@ EXPORT_SYMBOL(cfg80211_put_bss);
 void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
 {
 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
-	struct cfg80211_internal_bss *bss, *tmp1;
-	struct cfg80211_bss *nontrans_bss, *tmp;
+	struct cfg80211_internal_bss *bss;
 
 	if (WARN_ON(!pub))
 		return;
@@ -1796,21 +1816,11 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
 	bss = container_of(pub, struct cfg80211_internal_bss, pub);
 
 	spin_lock_bh(&rdev->bss_lock);
-	if (list_empty(&bss->list))
-		goto out;
 
-	list_for_each_entry_safe(nontrans_bss, tmp,
-				 &pub->nontrans_list,
-				 nontrans_list) {
-		tmp1 = container_of(nontrans_bss,
-				    struct cfg80211_internal_bss, pub);
-		if (__cfg80211_unlink_bss(rdev, tmp1))
+	if (!list_empty(&bss->list))
+		if (__cfg80211_unlink_bss(rdev, bss))
 			rdev->bss_generation++;
-	}
 
-	if (__cfg80211_unlink_bss(rdev, bss))
-		rdev->bss_generation++;
-out:
 	spin_unlock_bh(&rdev->bss_lock);
 }
 EXPORT_SYMBOL(cfg80211_unlink_bss);
-- 
2.17.2




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux