diff options
Diffstat (limited to 'net/tipc/subscr.c')
| -rw-r--r-- | net/tipc/subscr.c | 50 |
1 files changed, 18 insertions, 32 deletions
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index d38bb45d82e9..642437231ad5 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
| @@ -42,7 +42,7 @@ | |||
| 42 | /** | 42 | /** |
| 43 | * struct tipc_subscriber - TIPC network topology subscriber | 43 | * struct tipc_subscriber - TIPC network topology subscriber |
| 44 | * @conid: connection identifier to server connecting to subscriber | 44 | * @conid: connection identifier to server connecting to subscriber |
| 45 | * @lock: controll access to subscriber | 45 | * @lock: control access to subscriber |
| 46 | * @subscription_list: list of subscription objects for this subscriber | 46 | * @subscription_list: list of subscription objects for this subscriber |
| 47 | */ | 47 | */ |
| 48 | struct tipc_subscriber { | 48 | struct tipc_subscriber { |
| @@ -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); |
