diff options
Diffstat (limited to 'net/tipc/group.c')
-rw-r--r-- | net/tipc/group.c | 100 |
1 files changed, 62 insertions, 38 deletions
diff --git a/net/tipc/group.c b/net/tipc/group.c index bdc54be9c07e..6ca07f0da60c 100644 --- a/net/tipc/group.c +++ b/net/tipc/group.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #define ADV_ACTIVE (ADV_UNIT * 12) | 49 | #define ADV_ACTIVE (ADV_UNIT * 12) |
50 | 50 | ||
51 | enum mbr_state { | 51 | enum mbr_state { |
52 | MBR_DISCOVERED, | ||
53 | MBR_JOINING, | 52 | MBR_JOINING, |
54 | MBR_PUBLISHED, | 53 | MBR_PUBLISHED, |
55 | MBR_JOINED, | 54 | MBR_JOINED, |
@@ -141,7 +140,7 @@ static bool tipc_group_is_receiver(struct tipc_member *m) | |||
141 | 140 | ||
142 | static bool tipc_group_is_sender(struct tipc_member *m) | 141 | static bool tipc_group_is_sender(struct tipc_member *m) |
143 | { | 142 | { |
144 | return m && m->state >= MBR_JOINED; | 143 | return m && m->state != MBR_JOINING && m->state != MBR_PUBLISHED; |
145 | } | 144 | } |
146 | 145 | ||
147 | u32 tipc_group_exclude(struct tipc_group *grp) | 146 | u32 tipc_group_exclude(struct tipc_group *grp) |
@@ -184,6 +183,21 @@ struct tipc_group *tipc_group_create(struct net *net, u32 portid, | |||
184 | return NULL; | 183 | return NULL; |
185 | } | 184 | } |
186 | 185 | ||
186 | void tipc_group_join(struct net *net, struct tipc_group *grp, int *sk_rcvbuf) | ||
187 | { | ||
188 | struct rb_root *tree = &grp->members; | ||
189 | struct tipc_member *m, *tmp; | ||
190 | struct sk_buff_head xmitq; | ||
191 | |||
192 | skb_queue_head_init(&xmitq); | ||
193 | rbtree_postorder_for_each_entry_safe(m, tmp, tree, tree_node) { | ||
194 | tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, &xmitq); | ||
195 | tipc_group_update_member(m, 0); | ||
196 | } | ||
197 | tipc_node_distr_xmit(net, &xmitq); | ||
198 | *sk_rcvbuf = tipc_group_rcvbuf_limit(grp); | ||
199 | } | ||
200 | |||
187 | void tipc_group_delete(struct net *net, struct tipc_group *grp) | 201 | void tipc_group_delete(struct net *net, struct tipc_group *grp) |
188 | { | 202 | { |
189 | struct rb_root *tree = &grp->members; | 203 | struct rb_root *tree = &grp->members; |
@@ -274,7 +288,7 @@ static void tipc_group_add_to_tree(struct tipc_group *grp, | |||
274 | 288 | ||
275 | static struct tipc_member *tipc_group_create_member(struct tipc_group *grp, | 289 | static struct tipc_member *tipc_group_create_member(struct tipc_group *grp, |
276 | u32 node, u32 port, | 290 | u32 node, u32 port, |
277 | int state) | 291 | u32 instance, int state) |
278 | { | 292 | { |
279 | struct tipc_member *m; | 293 | struct tipc_member *m; |
280 | 294 | ||
@@ -287,6 +301,7 @@ static struct tipc_member *tipc_group_create_member(struct tipc_group *grp, | |||
287 | m->group = grp; | 301 | m->group = grp; |
288 | m->node = node; | 302 | m->node = node; |
289 | m->port = port; | 303 | m->port = port; |
304 | m->instance = instance; | ||
290 | m->bc_acked = grp->bc_snd_nxt - 1; | 305 | m->bc_acked = grp->bc_snd_nxt - 1; |
291 | grp->member_cnt++; | 306 | grp->member_cnt++; |
292 | tipc_group_add_to_tree(grp, m); | 307 | tipc_group_add_to_tree(grp, m); |
@@ -295,9 +310,10 @@ static struct tipc_member *tipc_group_create_member(struct tipc_group *grp, | |||
295 | return m; | 310 | return m; |
296 | } | 311 | } |
297 | 312 | ||
298 | void tipc_group_add_member(struct tipc_group *grp, u32 node, u32 port) | 313 | void tipc_group_add_member(struct tipc_group *grp, u32 node, |
314 | u32 port, u32 instance) | ||
299 | { | 315 | { |
300 | tipc_group_create_member(grp, node, port, MBR_DISCOVERED); | 316 | tipc_group_create_member(grp, node, port, instance, MBR_PUBLISHED); |
301 | } | 317 | } |
302 | 318 | ||
303 | static void tipc_group_delete_member(struct tipc_group *grp, | 319 | static void tipc_group_delete_member(struct tipc_group *grp, |
@@ -623,7 +639,6 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node, | |||
623 | tipc_group_proto_xmit(grp, pm, GRP_ADV_MSG, xmitq); | 639 | tipc_group_proto_xmit(grp, pm, GRP_ADV_MSG, xmitq); |
624 | break; | 640 | break; |
625 | case MBR_RECLAIMING: | 641 | case MBR_RECLAIMING: |
626 | case MBR_DISCOVERED: | ||
627 | case MBR_JOINING: | 642 | case MBR_JOINING: |
628 | case MBR_LEAVING: | 643 | case MBR_LEAVING: |
629 | default: | 644 | default: |
@@ -721,26 +736,26 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
721 | case GRP_JOIN_MSG: | 736 | case GRP_JOIN_MSG: |
722 | if (!m) | 737 | if (!m) |
723 | m = tipc_group_create_member(grp, node, port, | 738 | m = tipc_group_create_member(grp, node, port, |
724 | MBR_JOINING); | 739 | 0, MBR_JOINING); |
725 | if (!m) | 740 | if (!m) |
726 | return; | 741 | return; |
727 | m->bc_syncpt = msg_grp_bc_syncpt(hdr); | 742 | m->bc_syncpt = msg_grp_bc_syncpt(hdr); |
728 | m->bc_rcv_nxt = m->bc_syncpt; | 743 | m->bc_rcv_nxt = m->bc_syncpt; |
729 | m->window += msg_adv_win(hdr); | 744 | m->window += msg_adv_win(hdr); |
730 | 745 | ||
731 | /* Wait until PUBLISH event is received */ | 746 | /* Wait until PUBLISH event is received if necessary */ |
732 | if (m->state == MBR_DISCOVERED) { | 747 | if (m->state != MBR_PUBLISHED) |
733 | m->state = MBR_JOINING; | 748 | return; |
734 | } else if (m->state == MBR_PUBLISHED) { | 749 | |
735 | m->state = MBR_JOINED; | 750 | /* Member can be taken into service */ |
736 | *usr_wakeup = true; | 751 | m->state = MBR_JOINED; |
737 | m->usr_pending = false; | 752 | *usr_wakeup = true; |
738 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); | 753 | m->usr_pending = false; |
739 | tipc_group_create_event(grp, m, TIPC_PUBLISHED, | ||
740 | m->bc_syncpt, inputq); | ||
741 | } | ||
742 | list_del_init(&m->small_win); | 754 | list_del_init(&m->small_win); |
743 | tipc_group_update_member(m, 0); | 755 | tipc_group_update_member(m, 0); |
756 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); | ||
757 | tipc_group_create_event(grp, m, TIPC_PUBLISHED, | ||
758 | m->bc_syncpt, inputq); | ||
744 | return; | 759 | return; |
745 | case GRP_LEAVE_MSG: | 760 | case GRP_LEAVE_MSG: |
746 | if (!m) | 761 | if (!m) |
@@ -844,30 +859,36 @@ void tipc_group_member_evt(struct tipc_group *grp, | |||
844 | 859 | ||
845 | m = tipc_group_find_member(grp, node, port); | 860 | m = tipc_group_find_member(grp, node, port); |
846 | 861 | ||
847 | if (event == TIPC_PUBLISHED) { | 862 | switch (event) { |
848 | if (!m) | 863 | case TIPC_PUBLISHED: |
849 | m = tipc_group_create_member(grp, node, port, | 864 | /* Send and wait for arrival of JOIN message if necessary */ |
850 | MBR_DISCOVERED); | 865 | if (!m) { |
851 | if (!m) | 866 | m = tipc_group_create_member(grp, node, port, instance, |
852 | return; | 867 | MBR_PUBLISHED); |
868 | if (!m) | ||
869 | break; | ||
870 | tipc_group_update_member(m, 0); | ||
871 | tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq); | ||
872 | break; | ||
873 | } | ||
853 | 874 | ||
854 | m->instance = instance; | 875 | if (m->state != MBR_JOINING) |
876 | break; | ||
855 | 877 | ||
856 | /* Hold back event if JOIN message not yet received */ | 878 | /* Member can be taken into service */ |
857 | if (m->state == MBR_DISCOVERED) { | 879 | m->instance = instance; |
858 | m->state = MBR_PUBLISHED; | 880 | m->state = MBR_JOINED; |
859 | } else { | 881 | *usr_wakeup = true; |
860 | tipc_group_create_event(grp, m, TIPC_PUBLISHED, | 882 | m->usr_pending = false; |
861 | m->bc_syncpt, inputq); | 883 | list_del_init(&m->small_win); |
862 | m->state = MBR_JOINED; | ||
863 | *usr_wakeup = true; | ||
864 | m->usr_pending = false; | ||
865 | } | ||
866 | tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq); | ||
867 | tipc_group_update_member(m, 0); | 884 | tipc_group_update_member(m, 0); |
868 | } else if (event == TIPC_WITHDRAWN) { | 885 | tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq); |
886 | tipc_group_create_event(grp, m, TIPC_PUBLISHED, | ||
887 | m->bc_syncpt, inputq); | ||
888 | break; | ||
889 | case TIPC_WITHDRAWN: | ||
869 | if (!m) | 890 | if (!m) |
870 | return; | 891 | break; |
871 | 892 | ||
872 | *usr_wakeup = true; | 893 | *usr_wakeup = true; |
873 | m->usr_pending = false; | 894 | m->usr_pending = false; |
@@ -880,6 +901,9 @@ void tipc_group_member_evt(struct tipc_group *grp, | |||
880 | if (!tipc_node_is_up(net, node)) | 901 | if (!tipc_node_is_up(net, node)) |
881 | tipc_group_create_event(grp, m, TIPC_WITHDRAWN, | 902 | tipc_group_create_event(grp, m, TIPC_WITHDRAWN, |
882 | m->bc_rcv_nxt, inputq); | 903 | m->bc_rcv_nxt, inputq); |
904 | break; | ||
905 | default: | ||
906 | break; | ||
883 | } | 907 | } |
884 | *sk_rcvbuf = tipc_group_rcvbuf_limit(grp); | 908 | *sk_rcvbuf = tipc_group_rcvbuf_limit(grp); |
885 | } | 909 | } |