diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/tipc/bcast.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 3d37fa2c1464..2c4ecbe50082 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -531,10 +531,12 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
531 | { | 531 | { |
532 | static int send_count = 0; | 532 | static int send_count = 0; |
533 | 533 | ||
534 | struct node_map remains; | 534 | struct node_map *remains; |
535 | struct node_map remains_new; | 535 | struct node_map *remains_new; |
536 | struct node_map *remains_tmp; | ||
536 | int bp_index; | 537 | int bp_index; |
537 | int swap_time; | 538 | int swap_time; |
539 | int err; | ||
538 | 540 | ||
539 | /* Prepare buffer for broadcasting (if first time trying to send it) */ | 541 | /* Prepare buffer for broadcasting (if first time trying to send it) */ |
540 | 542 | ||
@@ -555,7 +557,9 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
555 | 557 | ||
556 | /* Send buffer over bearers until all targets reached */ | 558 | /* Send buffer over bearers until all targets reached */ |
557 | 559 | ||
558 | remains = tipc_cltr_bcast_nodes; | 560 | remains = kmalloc(sizeof(struct node_map), GFP_ATOMIC); |
561 | remains_new = kmalloc(sizeof(struct node_map), GFP_ATOMIC); | ||
562 | *remains = tipc_cltr_bcast_nodes; | ||
559 | 563 | ||
560 | for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { | 564 | for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { |
561 | struct bearer *p = bcbearer->bpairs[bp_index].primary; | 565 | struct bearer *p = bcbearer->bpairs[bp_index].primary; |
@@ -564,8 +568,8 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
564 | if (!p) | 568 | if (!p) |
565 | break; /* no more bearers to try */ | 569 | break; /* no more bearers to try */ |
566 | 570 | ||
567 | tipc_nmap_diff(&remains, &p->nodes, &remains_new); | 571 | tipc_nmap_diff(remains, &p->nodes, remains_new); |
568 | if (remains_new.count == remains.count) | 572 | if (remains_new->count == remains->count) |
569 | continue; /* bearer pair doesn't add anything */ | 573 | continue; /* bearer pair doesn't add anything */ |
570 | 574 | ||
571 | if (!p->publ.blocked && | 575 | if (!p->publ.blocked && |
@@ -583,17 +587,27 @@ swap: | |||
583 | bcbearer->bpairs[bp_index].primary = s; | 587 | bcbearer->bpairs[bp_index].primary = s; |
584 | bcbearer->bpairs[bp_index].secondary = p; | 588 | bcbearer->bpairs[bp_index].secondary = p; |
585 | update: | 589 | update: |
586 | if (remains_new.count == 0) | 590 | if (remains_new->count == 0) { |
587 | return TIPC_OK; | 591 | err = TIPC_OK; |
592 | goto out; | ||
593 | } | ||
588 | 594 | ||
595 | /* swap map */ | ||
596 | remains_tmp = remains; | ||
589 | remains = remains_new; | 597 | remains = remains_new; |
598 | remains_new = remains_tmp; | ||
590 | } | 599 | } |
591 | 600 | ||
592 | /* Unable to reach all targets */ | 601 | /* Unable to reach all targets */ |
593 | 602 | ||
594 | bcbearer->bearer.publ.blocked = 1; | 603 | bcbearer->bearer.publ.blocked = 1; |
595 | bcl->stats.bearer_congs++; | 604 | bcl->stats.bearer_congs++; |
596 | return ~TIPC_OK; | 605 | err = ~TIPC_OK; |
606 | |||
607 | out: | ||
608 | kfree(remains_new); | ||
609 | kfree(remains); | ||
610 | return err; | ||
597 | } | 611 | } |
598 | 612 | ||
599 | /** | 613 | /** |