aboutsummaryrefslogtreecommitdiffstats
path: root/net/llc/llc_core.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@mandriva.com>2005-09-22 03:43:05 -0400
committerArnaldo Carvalho de Melo <acme@mandriva.com>2005-09-22 03:43:05 -0400
commit6e2144b76840be09924de1626e2dcd7b315f75b3 (patch)
tree33044cb63f368270229e2b40aa2ad024325c7e8b /net/llc/llc_core.c
parent04e4223f44b89e50f275cb6b95a58ebe2c4909be (diff)
[LLC]: Use refcounting with struct llc_sap
Signed-off-by: Jochen Friedrich <jochen@scram.de> Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Diffstat (limited to 'net/llc/llc_core.c')
-rw-r--r--net/llc/llc_core.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c
index 9727455bf0e7..9ccff1266b26 100644
--- a/net/llc/llc_core.c
+++ b/net/llc/llc_core.c
@@ -40,6 +40,7 @@ static struct llc_sap *llc_sap_alloc(void)
40 sap->state = LLC_SAP_STATE_ACTIVE; 40 sap->state = LLC_SAP_STATE_ACTIVE;
41 memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN); 41 memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN);
42 rwlock_init(&sap->sk_list.lock); 42 rwlock_init(&sap->sk_list.lock);
43 atomic_set(&sap->refcnt, 1);
43 } 44 }
44 return sap; 45 return sap;
45} 46}
@@ -52,9 +53,7 @@ static struct llc_sap *llc_sap_alloc(void)
52 */ 53 */
53static void llc_add_sap(struct llc_sap *sap) 54static void llc_add_sap(struct llc_sap *sap)
54{ 55{
55 write_lock_bh(&llc_sap_list_lock);
56 list_add_tail(&sap->node, &llc_sap_list); 56 list_add_tail(&sap->node, &llc_sap_list);
57 write_unlock_bh(&llc_sap_list_lock);
58} 57}
59 58
60/** 59/**
@@ -70,11 +69,25 @@ static void llc_del_sap(struct llc_sap *sap)
70 write_unlock_bh(&llc_sap_list_lock); 69 write_unlock_bh(&llc_sap_list_lock);
71} 70}
72 71
72struct llc_sap *__llc_sap_find(unsigned char sap_value)
73{
74 struct llc_sap* sap;
75
76 list_for_each_entry(sap, &llc_sap_list, node)
77 if (sap->laddr.lsap == sap_value)
78 goto out;
79 sap = NULL;
80out:
81 return sap;
82}
83
73/** 84/**
74 * llc_sap_find - searchs a SAP in station 85 * llc_sap_find - searchs a SAP in station
75 * @sap_value: sap to be found 86 * @sap_value: sap to be found
76 * 87 *
77 * Searchs for a sap in the sap list of the LLC's station upon the sap ID. 88 * Searchs for a sap in the sap list of the LLC's station upon the sap ID.
89 * If the sap is found it will be refcounted and the user will have to do
90 * a llc_sap_put after use.
78 * Returns the sap or %NULL if not found. 91 * Returns the sap or %NULL if not found.
79 */ 92 */
80struct llc_sap *llc_sap_find(unsigned char sap_value) 93struct llc_sap *llc_sap_find(unsigned char sap_value)
@@ -82,11 +95,9 @@ struct llc_sap *llc_sap_find(unsigned char sap_value)
82 struct llc_sap* sap; 95 struct llc_sap* sap;
83 96
84 read_lock_bh(&llc_sap_list_lock); 97 read_lock_bh(&llc_sap_list_lock);
85 list_for_each_entry(sap, &llc_sap_list, node) 98 sap = __llc_sap_find(sap_value);
86 if (sap->laddr.lsap == sap_value) 99 if (sap)
87 goto out; 100 llc_sap_hold(sap);
88 sap = NULL;
89out:
90 read_unlock_bh(&llc_sap_list_lock); 101 read_unlock_bh(&llc_sap_list_lock);
91 return sap; 102 return sap;
92} 103}
@@ -106,19 +117,20 @@ struct llc_sap *llc_sap_open(unsigned char lsap,
106 struct packet_type *pt, 117 struct packet_type *pt,
107 struct net_device *orig_dev)) 118 struct net_device *orig_dev))
108{ 119{
109 struct llc_sap *sap = llc_sap_find(lsap); 120 struct llc_sap *sap = NULL;
110 121
111 if (sap) { /* SAP already exists */ 122 write_lock_bh(&llc_sap_list_lock);
112 sap = NULL; 123 if (__llc_sap_find(lsap)) /* SAP already exists */
113 goto out; 124 goto out;
114 }
115 sap = llc_sap_alloc(); 125 sap = llc_sap_alloc();
116 if (!sap) 126 if (!sap)
117 goto out; 127 goto out;
118 sap->laddr.lsap = lsap; 128 sap->laddr.lsap = lsap;
119 sap->rcv_func = func; 129 sap->rcv_func = func;
130 llc_sap_hold(sap);
120 llc_add_sap(sap); 131 llc_add_sap(sap);
121out: 132out:
133 write_unlock_bh(&llc_sap_list_lock);
122 return sap; 134 return sap;
123} 135}
124 136