diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/group.c | 64 | ||||
-rw-r--r-- | net/tipc/group.h | 2 | ||||
-rw-r--r-- | net/tipc/socket.c | 8 |
3 files changed, 41 insertions, 33 deletions
diff --git a/net/tipc/group.c b/net/tipc/group.c index 1908773c9fca..497ee34bfab9 100644 --- a/net/tipc/group.c +++ b/net/tipc/group.c | |||
@@ -74,7 +74,6 @@ struct tipc_member { | |||
74 | u16 bc_rcv_nxt; | 74 | u16 bc_rcv_nxt; |
75 | u16 bc_syncpt; | 75 | u16 bc_syncpt; |
76 | u16 bc_acked; | 76 | u16 bc_acked; |
77 | bool usr_pending; | ||
78 | }; | 77 | }; |
79 | 78 | ||
80 | struct tipc_group { | 79 | struct tipc_group { |
@@ -96,11 +95,27 @@ struct tipc_group { | |||
96 | u16 bc_ackers; | 95 | u16 bc_ackers; |
97 | bool loopback; | 96 | bool loopback; |
98 | bool events; | 97 | bool events; |
98 | bool open; | ||
99 | }; | 99 | }; |
100 | 100 | ||
101 | static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m, | 101 | static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m, |
102 | int mtyp, struct sk_buff_head *xmitq); | 102 | int mtyp, struct sk_buff_head *xmitq); |
103 | 103 | ||
104 | bool tipc_group_is_open(struct tipc_group *grp) | ||
105 | { | ||
106 | return grp->open; | ||
107 | } | ||
108 | |||
109 | static void tipc_group_open(struct tipc_member *m, bool *wakeup) | ||
110 | { | ||
111 | *wakeup = false; | ||
112 | if (list_empty(&m->small_win)) | ||
113 | return; | ||
114 | list_del_init(&m->small_win); | ||
115 | m->group->open = true; | ||
116 | *wakeup = true; | ||
117 | } | ||
118 | |||
104 | static void tipc_group_decr_active(struct tipc_group *grp, | 119 | static void tipc_group_decr_active(struct tipc_group *grp, |
105 | struct tipc_member *m) | 120 | struct tipc_member *m) |
106 | { | 121 | { |
@@ -406,20 +421,20 @@ bool tipc_group_cong(struct tipc_group *grp, u32 dnode, u32 dport, | |||
406 | int adv, state; | 421 | int adv, state; |
407 | 422 | ||
408 | m = tipc_group_find_dest(grp, dnode, dport); | 423 | m = tipc_group_find_dest(grp, dnode, dport); |
409 | *mbr = m; | 424 | if (!tipc_group_is_receiver(m)) { |
410 | if (!m) | 425 | *mbr = NULL; |
411 | return false; | 426 | return false; |
412 | if (m->usr_pending) | 427 | } |
413 | return true; | 428 | *mbr = m; |
429 | |||
414 | if (m->window >= len) | 430 | if (m->window >= len) |
415 | return false; | 431 | return false; |
416 | m->usr_pending = true; | 432 | |
433 | grp->open = false; | ||
417 | 434 | ||
418 | /* If not fully advertised, do it now to prevent mutual blocking */ | 435 | /* If not fully advertised, do it now to prevent mutual blocking */ |
419 | adv = m->advertised; | 436 | adv = m->advertised; |
420 | state = m->state; | 437 | state = m->state; |
421 | if (state < MBR_JOINED) | ||
422 | return true; | ||
423 | if (state == MBR_JOINED && adv == ADV_IDLE) | 438 | if (state == MBR_JOINED && adv == ADV_IDLE) |
424 | return true; | 439 | return true; |
425 | if (state == MBR_ACTIVE && adv == ADV_ACTIVE) | 440 | if (state == MBR_ACTIVE && adv == ADV_ACTIVE) |
@@ -437,9 +452,10 @@ bool tipc_group_bc_cong(struct tipc_group *grp, int len) | |||
437 | struct tipc_member *m = NULL; | 452 | struct tipc_member *m = NULL; |
438 | 453 | ||
439 | /* If prev bcast was replicast, reject until all receivers have acked */ | 454 | /* If prev bcast was replicast, reject until all receivers have acked */ |
440 | if (grp->bc_ackers) | 455 | if (grp->bc_ackers) { |
456 | grp->open = false; | ||
441 | return true; | 457 | return true; |
442 | 458 | } | |
443 | if (list_empty(&grp->small_win)) | 459 | if (list_empty(&grp->small_win)) |
444 | return false; | 460 | return false; |
445 | 461 | ||
@@ -754,9 +770,7 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
754 | 770 | ||
755 | /* Member can be taken into service */ | 771 | /* Member can be taken into service */ |
756 | m->state = MBR_JOINED; | 772 | m->state = MBR_JOINED; |
757 | *usr_wakeup = true; | 773 | tipc_group_open(m, usr_wakeup); |
758 | m->usr_pending = false; | ||
759 | list_del_init(&m->small_win); | ||
760 | tipc_group_update_member(m, 0); | 774 | tipc_group_update_member(m, 0); |
761 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); | 775 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); |
762 | tipc_group_create_event(grp, m, TIPC_PUBLISHED, | 776 | tipc_group_create_event(grp, m, TIPC_PUBLISHED, |
@@ -767,8 +781,7 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
767 | return; | 781 | return; |
768 | m->bc_syncpt = msg_grp_bc_syncpt(hdr); | 782 | m->bc_syncpt = msg_grp_bc_syncpt(hdr); |
769 | list_del_init(&m->list); | 783 | list_del_init(&m->list); |
770 | list_del_init(&m->small_win); | 784 | tipc_group_open(m, usr_wakeup); |
771 | *usr_wakeup = true; | ||
772 | tipc_group_decr_active(grp, m); | 785 | tipc_group_decr_active(grp, m); |
773 | m->state = MBR_LEAVING; | 786 | m->state = MBR_LEAVING; |
774 | tipc_group_create_event(grp, m, TIPC_WITHDRAWN, | 787 | tipc_group_create_event(grp, m, TIPC_WITHDRAWN, |
@@ -778,26 +791,25 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
778 | if (!m) | 791 | if (!m) |
779 | return; | 792 | return; |
780 | m->window += msg_adv_win(hdr); | 793 | m->window += msg_adv_win(hdr); |
781 | *usr_wakeup = m->usr_pending; | 794 | tipc_group_open(m, usr_wakeup); |
782 | m->usr_pending = false; | ||
783 | list_del_init(&m->small_win); | ||
784 | return; | 795 | return; |
785 | case GRP_ACK_MSG: | 796 | case GRP_ACK_MSG: |
786 | if (!m) | 797 | if (!m) |
787 | return; | 798 | return; |
788 | m->bc_acked = msg_grp_bc_acked(hdr); | 799 | m->bc_acked = msg_grp_bc_acked(hdr); |
789 | if (--grp->bc_ackers) | 800 | if (--grp->bc_ackers) |
790 | break; | 801 | return; |
802 | list_del_init(&m->small_win); | ||
803 | m->group->open = true; | ||
791 | *usr_wakeup = true; | 804 | *usr_wakeup = true; |
792 | m->usr_pending = false; | 805 | tipc_group_update_member(m, 0); |
793 | return; | 806 | return; |
794 | case GRP_RECLAIM_MSG: | 807 | case GRP_RECLAIM_MSG: |
795 | if (!m) | 808 | if (!m) |
796 | return; | 809 | return; |
797 | *usr_wakeup = m->usr_pending; | ||
798 | m->usr_pending = false; | ||
799 | tipc_group_proto_xmit(grp, m, GRP_REMIT_MSG, xmitq); | 810 | tipc_group_proto_xmit(grp, m, GRP_REMIT_MSG, xmitq); |
800 | m->window = ADV_IDLE; | 811 | m->window = ADV_IDLE; |
812 | tipc_group_open(m, usr_wakeup); | ||
801 | return; | 813 | return; |
802 | case GRP_REMIT_MSG: | 814 | case GRP_REMIT_MSG: |
803 | if (!m || m->state != MBR_RECLAIMING) | 815 | if (!m || m->state != MBR_RECLAIMING) |
@@ -883,9 +895,7 @@ void tipc_group_member_evt(struct tipc_group *grp, | |||
883 | /* Member can be taken into service */ | 895 | /* Member can be taken into service */ |
884 | m->instance = instance; | 896 | m->instance = instance; |
885 | m->state = MBR_JOINED; | 897 | m->state = MBR_JOINED; |
886 | *usr_wakeup = true; | 898 | tipc_group_open(m, usr_wakeup); |
887 | m->usr_pending = false; | ||
888 | list_del_init(&m->small_win); | ||
889 | tipc_group_update_member(m, 0); | 899 | tipc_group_update_member(m, 0); |
890 | tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq); | 900 | tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq); |
891 | tipc_group_create_event(grp, m, TIPC_PUBLISHED, | 901 | tipc_group_create_event(grp, m, TIPC_PUBLISHED, |
@@ -895,12 +905,10 @@ void tipc_group_member_evt(struct tipc_group *grp, | |||
895 | if (!m) | 905 | if (!m) |
896 | break; | 906 | break; |
897 | 907 | ||
898 | *usr_wakeup = true; | ||
899 | m->usr_pending = false; | ||
900 | tipc_group_decr_active(grp, m); | 908 | tipc_group_decr_active(grp, m); |
901 | m->state = MBR_LEAVING; | 909 | m->state = MBR_LEAVING; |
902 | list_del_init(&m->list); | 910 | list_del_init(&m->list); |
903 | list_del_init(&m->small_win); | 911 | tipc_group_open(m, usr_wakeup); |
904 | 912 | ||
905 | /* Only send event if no LEAVE message can be expected */ | 913 | /* Only send event if no LEAVE message can be expected */ |
906 | if (!tipc_node_is_up(net, node)) | 914 | if (!tipc_node_is_up(net, node)) |
diff --git a/net/tipc/group.h b/net/tipc/group.h index dee79477d499..f4a596ed9848 100644 --- a/net/tipc/group.h +++ b/net/tipc/group.h | |||
@@ -67,9 +67,9 @@ void tipc_group_update_bc_members(struct tipc_group *grp, int len, bool ack); | |||
67 | bool tipc_group_cong(struct tipc_group *grp, u32 dnode, u32 dport, | 67 | bool tipc_group_cong(struct tipc_group *grp, u32 dnode, u32 dport, |
68 | int len, struct tipc_member **m); | 68 | int len, struct tipc_member **m); |
69 | bool tipc_group_bc_cong(struct tipc_group *grp, int len); | 69 | bool tipc_group_bc_cong(struct tipc_group *grp, int len); |
70 | bool tipc_group_is_open(struct tipc_group *grp); | ||
70 | void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node, | 71 | void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node, |
71 | u32 port, struct sk_buff_head *xmitq); | 72 | u32 port, struct sk_buff_head *xmitq); |
72 | u16 tipc_group_bc_snd_nxt(struct tipc_group *grp); | 73 | u16 tipc_group_bc_snd_nxt(struct tipc_group *grp); |
73 | void tipc_group_update_member(struct tipc_member *m, int len); | 74 | void tipc_group_update_member(struct tipc_member *m, int len); |
74 | int tipc_group_size(struct tipc_group *grp); | ||
75 | #endif | 75 | #endif |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index b24dab3996c9..1f236271766c 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -715,7 +715,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
715 | { | 715 | { |
716 | struct sock *sk = sock->sk; | 716 | struct sock *sk = sock->sk; |
717 | struct tipc_sock *tsk = tipc_sk(sk); | 717 | struct tipc_sock *tsk = tipc_sk(sk); |
718 | struct tipc_group *grp = tsk->group; | 718 | struct tipc_group *grp; |
719 | u32 revents = 0; | 719 | u32 revents = 0; |
720 | 720 | ||
721 | sock_poll_wait(file, sk_sleep(sk), wait); | 721 | sock_poll_wait(file, sk_sleep(sk), wait); |
@@ -736,9 +736,9 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
736 | revents |= POLLIN | POLLRDNORM; | 736 | revents |= POLLIN | POLLRDNORM; |
737 | break; | 737 | break; |
738 | case TIPC_OPEN: | 738 | case TIPC_OPEN: |
739 | if (!grp || tipc_group_size(grp)) | 739 | grp = tsk->group; |
740 | if (!tsk->cong_link_cnt) | 740 | if ((!grp || tipc_group_is_open(grp)) && !tsk->cong_link_cnt) |
741 | revents |= POLLOUT; | 741 | revents |= POLLOUT; |
742 | if (!tipc_sk_type_connectionless(sk)) | 742 | if (!tipc_sk_type_connectionless(sk)) |
743 | break; | 743 | break; |
744 | if (skb_queue_empty(&sk->sk_receive_queue)) | 744 | if (skb_queue_empty(&sk->sk_receive_queue)) |