diff options
Diffstat (limited to 'net/tipc/subscr.c')
-rw-r--r-- | net/tipc/subscr.c | 48 |
1 files changed, 17 insertions, 31 deletions
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 7cb0bd5b1176..642437231ad5 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
@@ -96,20 +96,16 @@ static void subscr_send_event(struct tipc_subscription *sub, u32 found_lower, | |||
96 | { | 96 | { |
97 | struct tipc_subscriber *subscriber = sub->subscriber; | 97 | struct tipc_subscriber *subscriber = sub->subscriber; |
98 | struct kvec msg_sect; | 98 | struct kvec msg_sect; |
99 | int ret; | ||
100 | 99 | ||
101 | msg_sect.iov_base = (void *)&sub->evt; | 100 | msg_sect.iov_base = (void *)&sub->evt; |
102 | msg_sect.iov_len = sizeof(struct tipc_event); | 101 | msg_sect.iov_len = sizeof(struct tipc_event); |
103 | |||
104 | sub->evt.event = htohl(event, sub->swap); | 102 | sub->evt.event = htohl(event, sub->swap); |
105 | sub->evt.found_lower = htohl(found_lower, sub->swap); | 103 | sub->evt.found_lower = htohl(found_lower, sub->swap); |
106 | sub->evt.found_upper = htohl(found_upper, sub->swap); | 104 | sub->evt.found_upper = htohl(found_upper, sub->swap); |
107 | sub->evt.port.ref = htohl(port_ref, sub->swap); | 105 | sub->evt.port.ref = htohl(port_ref, sub->swap); |
108 | sub->evt.port.node = htohl(node, sub->swap); | 106 | sub->evt.port.node = htohl(node, sub->swap); |
109 | ret = tipc_conn_sendmsg(&topsrv, subscriber->conid, NULL, | 107 | tipc_conn_sendmsg(&topsrv, subscriber->conid, NULL, msg_sect.iov_base, |
110 | msg_sect.iov_base, msg_sect.iov_len); | 108 | msg_sect.iov_len); |
111 | if (ret < 0) | ||
112 | pr_err("Sending subscription event failed, no memory\n"); | ||
113 | } | 109 | } |
114 | 110 | ||
115 | /** | 111 | /** |
@@ -153,14 +149,6 @@ static void subscr_timeout(struct tipc_subscription *sub) | |||
153 | /* The spin lock per subscriber is used to protect its members */ | 149 | /* The spin lock per subscriber is used to protect its members */ |
154 | spin_lock_bh(&subscriber->lock); | 150 | spin_lock_bh(&subscriber->lock); |
155 | 151 | ||
156 | /* Validate if the connection related to the subscriber is | ||
157 | * closed (in case subscriber is terminating) | ||
158 | */ | ||
159 | if (subscriber->conid == 0) { | ||
160 | spin_unlock_bh(&subscriber->lock); | ||
161 | return; | ||
162 | } | ||
163 | |||
164 | /* Validate timeout (in case subscription is being cancelled) */ | 152 | /* Validate timeout (in case subscription is being cancelled) */ |
165 | if (sub->timeout == TIPC_WAIT_FOREVER) { | 153 | if (sub->timeout == TIPC_WAIT_FOREVER) { |
166 | spin_unlock_bh(&subscriber->lock); | 154 | spin_unlock_bh(&subscriber->lock); |
@@ -215,9 +203,6 @@ static void subscr_release(struct tipc_subscriber *subscriber) | |||
215 | 203 | ||
216 | spin_lock_bh(&subscriber->lock); | 204 | spin_lock_bh(&subscriber->lock); |
217 | 205 | ||
218 | /* Invalidate subscriber reference */ | ||
219 | subscriber->conid = 0; | ||
220 | |||
221 | /* Destroy any existing subscriptions for subscriber */ | 206 | /* Destroy any existing subscriptions for subscriber */ |
222 | list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, | 207 | list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, |
223 | subscription_list) { | 208 | subscription_list) { |
@@ -278,9 +263,9 @@ static void subscr_cancel(struct tipc_subscr *s, | |||
278 | * | 263 | * |
279 | * Called with subscriber lock held. | 264 | * Called with subscriber lock held. |
280 | */ | 265 | */ |
281 | static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, | 266 | static int subscr_subscribe(struct tipc_subscr *s, |
282 | struct tipc_subscriber *subscriber) | 267 | struct tipc_subscriber *subscriber, |
283 | { | 268 | struct tipc_subscription **sub_p) { |
284 | struct tipc_subscription *sub; | 269 | struct tipc_subscription *sub; |
285 | int swap; | 270 | int swap; |
286 | 271 | ||
@@ -291,23 +276,21 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, | |||
291 | if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { | 276 | if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { |
292 | s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); | 277 | s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); |
293 | subscr_cancel(s, subscriber); | 278 | subscr_cancel(s, subscriber); |
294 | return NULL; | 279 | return 0; |
295 | } | 280 | } |
296 | 281 | ||
297 | /* Refuse subscription if global limit exceeded */ | 282 | /* Refuse subscription if global limit exceeded */ |
298 | if (atomic_read(&subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) { | 283 | if (atomic_read(&subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) { |
299 | pr_warn("Subscription rejected, limit reached (%u)\n", | 284 | pr_warn("Subscription rejected, limit reached (%u)\n", |
300 | TIPC_MAX_SUBSCRIPTIONS); | 285 | TIPC_MAX_SUBSCRIPTIONS); |
301 | subscr_terminate(subscriber); | 286 | return -EINVAL; |
302 | return NULL; | ||
303 | } | 287 | } |
304 | 288 | ||
305 | /* Allocate subscription object */ | 289 | /* Allocate subscription object */ |
306 | sub = kmalloc(sizeof(*sub), GFP_ATOMIC); | 290 | sub = kmalloc(sizeof(*sub), GFP_ATOMIC); |
307 | if (!sub) { | 291 | if (!sub) { |
308 | pr_warn("Subscription rejected, no memory\n"); | 292 | pr_warn("Subscription rejected, no memory\n"); |
309 | subscr_terminate(subscriber); | 293 | return -ENOMEM; |
310 | return NULL; | ||
311 | } | 294 | } |
312 | 295 | ||
313 | /* Initialize subscription object */ | 296 | /* Initialize subscription object */ |
@@ -321,8 +304,7 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, | |||
321 | (sub->seq.lower > sub->seq.upper)) { | 304 | (sub->seq.lower > sub->seq.upper)) { |
322 | pr_warn("Subscription rejected, illegal request\n"); | 305 | pr_warn("Subscription rejected, illegal request\n"); |
323 | kfree(sub); | 306 | kfree(sub); |
324 | subscr_terminate(subscriber); | 307 | return -EINVAL; |
325 | return NULL; | ||
326 | } | 308 | } |
327 | INIT_LIST_HEAD(&sub->nameseq_list); | 309 | INIT_LIST_HEAD(&sub->nameseq_list); |
328 | list_add(&sub->subscription_list, &subscriber->subscription_list); | 310 | list_add(&sub->subscription_list, &subscriber->subscription_list); |
@@ -335,8 +317,8 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, | |||
335 | (Handler)subscr_timeout, (unsigned long)sub); | 317 | (Handler)subscr_timeout, (unsigned long)sub); |
336 | k_start_timer(&sub->timer, sub->timeout); | 318 | k_start_timer(&sub->timer, sub->timeout); |
337 | } | 319 | } |
338 | 320 | *sub_p = sub; | |
339 | return sub; | 321 | return 0; |
340 | } | 322 | } |
341 | 323 | ||
342 | /* Handle one termination request for the subscriber */ | 324 | /* Handle one termination request for the subscriber */ |
@@ -350,10 +332,14 @@ static void subscr_conn_msg_event(int conid, struct sockaddr_tipc *addr, | |||
350 | void *usr_data, void *buf, size_t len) | 332 | void *usr_data, void *buf, size_t len) |
351 | { | 333 | { |
352 | struct tipc_subscriber *subscriber = usr_data; | 334 | struct tipc_subscriber *subscriber = usr_data; |
353 | struct tipc_subscription *sub; | 335 | struct tipc_subscription *sub = NULL; |
354 | 336 | ||
355 | spin_lock_bh(&subscriber->lock); | 337 | spin_lock_bh(&subscriber->lock); |
356 | sub = subscr_subscribe((struct tipc_subscr *)buf, subscriber); | 338 | if (subscr_subscribe((struct tipc_subscr *)buf, subscriber, &sub) < 0) { |
339 | spin_unlock_bh(&subscriber->lock); | ||
340 | subscr_terminate(subscriber); | ||
341 | return; | ||
342 | } | ||
357 | if (sub) | 343 | if (sub) |
358 | tipc_nametbl_subscribe(sub); | 344 | tipc_nametbl_subscribe(sub); |
359 | spin_unlock_bh(&subscriber->lock); | 345 | spin_unlock_bh(&subscriber->lock); |