diff options
Diffstat (limited to 'net/tipc/subscr.c')
| -rw-r--r-- | net/tipc/subscr.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 11c9ae00837d..642437231ad5 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
| @@ -263,9 +263,9 @@ static void subscr_cancel(struct tipc_subscr *s, | |||
| 263 | * | 263 | * |
| 264 | * Called with subscriber lock held. | 264 | * Called with subscriber lock held. |
| 265 | */ | 265 | */ |
| 266 | static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, | 266 | static int subscr_subscribe(struct tipc_subscr *s, |
| 267 | struct tipc_subscriber *subscriber) | 267 | struct tipc_subscriber *subscriber, |
| 268 | { | 268 | struct tipc_subscription **sub_p) { |
| 269 | struct tipc_subscription *sub; | 269 | struct tipc_subscription *sub; |
| 270 | int swap; | 270 | int swap; |
| 271 | 271 | ||
| @@ -276,23 +276,21 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, | |||
| 276 | if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { | 276 | if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { |
| 277 | s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); | 277 | s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); |
| 278 | subscr_cancel(s, subscriber); | 278 | subscr_cancel(s, subscriber); |
| 279 | return NULL; | 279 | return 0; |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | /* Refuse subscription if global limit exceeded */ | 282 | /* Refuse subscription if global limit exceeded */ |
| 283 | if (atomic_read(&subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) { | 283 | if (atomic_read(&subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) { |
| 284 | pr_warn("Subscription rejected, limit reached (%u)\n", | 284 | pr_warn("Subscription rejected, limit reached (%u)\n", |
| 285 | TIPC_MAX_SUBSCRIPTIONS); | 285 | TIPC_MAX_SUBSCRIPTIONS); |
| 286 | subscr_terminate(subscriber); | 286 | return -EINVAL; |
| 287 | return NULL; | ||
| 288 | } | 287 | } |
| 289 | 288 | ||
| 290 | /* Allocate subscription object */ | 289 | /* Allocate subscription object */ |
| 291 | sub = kmalloc(sizeof(*sub), GFP_ATOMIC); | 290 | sub = kmalloc(sizeof(*sub), GFP_ATOMIC); |
| 292 | if (!sub) { | 291 | if (!sub) { |
| 293 | pr_warn("Subscription rejected, no memory\n"); | 292 | pr_warn("Subscription rejected, no memory\n"); |
| 294 | subscr_terminate(subscriber); | 293 | return -ENOMEM; |
| 295 | return NULL; | ||
| 296 | } | 294 | } |
| 297 | 295 | ||
| 298 | /* Initialize subscription object */ | 296 | /* Initialize subscription object */ |
| @@ -306,8 +304,7 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, | |||
| 306 | (sub->seq.lower > sub->seq.upper)) { | 304 | (sub->seq.lower > sub->seq.upper)) { |
| 307 | pr_warn("Subscription rejected, illegal request\n"); | 305 | pr_warn("Subscription rejected, illegal request\n"); |
| 308 | kfree(sub); | 306 | kfree(sub); |
| 309 | subscr_terminate(subscriber); | 307 | return -EINVAL; |
| 310 | return NULL; | ||
| 311 | } | 308 | } |
| 312 | INIT_LIST_HEAD(&sub->nameseq_list); | 309 | INIT_LIST_HEAD(&sub->nameseq_list); |
| 313 | list_add(&sub->subscription_list, &subscriber->subscription_list); | 310 | list_add(&sub->subscription_list, &subscriber->subscription_list); |
| @@ -320,8 +317,8 @@ static struct tipc_subscription *subscr_subscribe(struct tipc_subscr *s, | |||
| 320 | (Handler)subscr_timeout, (unsigned long)sub); | 317 | (Handler)subscr_timeout, (unsigned long)sub); |
| 321 | k_start_timer(&sub->timer, sub->timeout); | 318 | k_start_timer(&sub->timer, sub->timeout); |
| 322 | } | 319 | } |
| 323 | 320 | *sub_p = sub; | |
| 324 | return sub; | 321 | return 0; |
| 325 | } | 322 | } |
| 326 | 323 | ||
| 327 | /* Handle one termination request for the subscriber */ | 324 | /* Handle one termination request for the subscriber */ |
| @@ -335,10 +332,14 @@ static void subscr_conn_msg_event(int conid, struct sockaddr_tipc *addr, | |||
| 335 | void *usr_data, void *buf, size_t len) | 332 | void *usr_data, void *buf, size_t len) |
| 336 | { | 333 | { |
| 337 | struct tipc_subscriber *subscriber = usr_data; | 334 | struct tipc_subscriber *subscriber = usr_data; |
| 338 | struct tipc_subscription *sub; | 335 | struct tipc_subscription *sub = NULL; |
| 339 | 336 | ||
| 340 | spin_lock_bh(&subscriber->lock); | 337 | spin_lock_bh(&subscriber->lock); |
| 341 | 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 | } | ||
| 342 | if (sub) | 343 | if (sub) |
| 343 | tipc_nametbl_subscribe(sub); | 344 | tipc_nametbl_subscribe(sub); |
| 344 | spin_unlock_bh(&subscriber->lock); | 345 | spin_unlock_bh(&subscriber->lock); |
