aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/group.c19
-rw-r--r--net/tipc/group.h4
-rw-r--r--net/tipc/socket.c7
3 files changed, 13 insertions, 17 deletions
diff --git a/net/tipc/group.c b/net/tipc/group.c
index 497ee34bfab9..122162a31816 100644
--- a/net/tipc/group.c
+++ b/net/tipc/group.c
@@ -93,26 +93,21 @@ struct tipc_group {
93 u16 max_active; 93 u16 max_active;
94 u16 bc_snd_nxt; 94 u16 bc_snd_nxt;
95 u16 bc_ackers; 95 u16 bc_ackers;
96 bool *open;
96 bool loopback; 97 bool loopback;
97 bool events; 98 bool events;
98 bool open;
99}; 99};
100 100
101static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m, 101static 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
104bool tipc_group_is_open(struct tipc_group *grp)
105{
106 return grp->open;
107}
108
109static void tipc_group_open(struct tipc_member *m, bool *wakeup) 104static void tipc_group_open(struct tipc_member *m, bool *wakeup)
110{ 105{
111 *wakeup = false; 106 *wakeup = false;
112 if (list_empty(&m->small_win)) 107 if (list_empty(&m->small_win))
113 return; 108 return;
114 list_del_init(&m->small_win); 109 list_del_init(&m->small_win);
115 m->group->open = true; 110 *m->group->open = true;
116 *wakeup = true; 111 *wakeup = true;
117} 112}
118 113
@@ -170,7 +165,8 @@ int tipc_group_size(struct tipc_group *grp)
170} 165}
171 166
172struct tipc_group *tipc_group_create(struct net *net, u32 portid, 167struct tipc_group *tipc_group_create(struct net *net, u32 portid,
173 struct tipc_group_req *mreq) 168 struct tipc_group_req *mreq,
169 bool *group_is_open)
174{ 170{
175 u32 filter = TIPC_SUB_PORTS | TIPC_SUB_NO_STATUS; 171 u32 filter = TIPC_SUB_PORTS | TIPC_SUB_NO_STATUS;
176 bool global = mreq->scope != TIPC_NODE_SCOPE; 172 bool global = mreq->scope != TIPC_NODE_SCOPE;
@@ -192,6 +188,7 @@ struct tipc_group *tipc_group_create(struct net *net, u32 portid,
192 grp->scope = mreq->scope; 188 grp->scope = mreq->scope;
193 grp->loopback = mreq->flags & TIPC_GROUP_LOOPBACK; 189 grp->loopback = mreq->flags & TIPC_GROUP_LOOPBACK;
194 grp->events = mreq->flags & TIPC_GROUP_MEMBER_EVTS; 190 grp->events = mreq->flags & TIPC_GROUP_MEMBER_EVTS;
191 grp->open = group_is_open;
195 filter |= global ? TIPC_SUB_CLUSTER_SCOPE : TIPC_SUB_NODE_SCOPE; 192 filter |= global ? TIPC_SUB_CLUSTER_SCOPE : TIPC_SUB_NODE_SCOPE;
196 if (tipc_topsrv_kern_subscr(net, portid, type, 0, ~0, 193 if (tipc_topsrv_kern_subscr(net, portid, type, 0, ~0,
197 filter, &grp->subid)) 194 filter, &grp->subid))
@@ -430,7 +427,7 @@ bool tipc_group_cong(struct tipc_group *grp, u32 dnode, u32 dport,
430 if (m->window >= len) 427 if (m->window >= len)
431 return false; 428 return false;
432 429
433 grp->open = false; 430 *grp->open = false;
434 431
435 /* If not fully advertised, do it now to prevent mutual blocking */ 432 /* If not fully advertised, do it now to prevent mutual blocking */
436 adv = m->advertised; 433 adv = m->advertised;
@@ -453,7 +450,7 @@ bool tipc_group_bc_cong(struct tipc_group *grp, int len)
453 450
454 /* If prev bcast was replicast, reject until all receivers have acked */ 451 /* If prev bcast was replicast, reject until all receivers have acked */
455 if (grp->bc_ackers) { 452 if (grp->bc_ackers) {
456 grp->open = false; 453 *grp->open = false;
457 return true; 454 return true;
458 } 455 }
459 if (list_empty(&grp->small_win)) 456 if (list_empty(&grp->small_win))
@@ -800,7 +797,7 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
800 if (--grp->bc_ackers) 797 if (--grp->bc_ackers)
801 return; 798 return;
802 list_del_init(&m->small_win); 799 list_del_init(&m->small_win);
803 m->group->open = true; 800 *m->group->open = true;
804 *usr_wakeup = true; 801 *usr_wakeup = true;
805 tipc_group_update_member(m, 0); 802 tipc_group_update_member(m, 0);
806 return; 803 return;
diff --git a/net/tipc/group.h b/net/tipc/group.h
index f4a596ed9848..5996af6e9f1d 100644
--- a/net/tipc/group.h
+++ b/net/tipc/group.h
@@ -43,7 +43,8 @@ struct tipc_member;
43struct tipc_msg; 43struct tipc_msg;
44 44
45struct tipc_group *tipc_group_create(struct net *net, u32 portid, 45struct tipc_group *tipc_group_create(struct net *net, u32 portid,
46 struct tipc_group_req *mreq); 46 struct tipc_group_req *mreq,
47 bool *group_is_open);
47void tipc_group_join(struct net *net, struct tipc_group *grp, int *sk_rcv_buf); 48void tipc_group_join(struct net *net, struct tipc_group *grp, int *sk_rcv_buf);
48void tipc_group_delete(struct net *net, struct tipc_group *grp); 49void tipc_group_delete(struct net *net, struct tipc_group *grp);
49void tipc_group_add_member(struct tipc_group *grp, u32 node, 50void tipc_group_add_member(struct tipc_group *grp, u32 node,
@@ -67,7 +68,6 @@ void tipc_group_update_bc_members(struct tipc_group *grp, int len, bool ack);
67bool tipc_group_cong(struct tipc_group *grp, u32 dnode, u32 dport, 68bool tipc_group_cong(struct tipc_group *grp, u32 dnode, u32 dport,
68 int len, struct tipc_member **m); 69 int len, struct tipc_member **m);
69bool tipc_group_bc_cong(struct tipc_group *grp, int len); 70bool tipc_group_bc_cong(struct tipc_group *grp, int len);
70bool tipc_group_is_open(struct tipc_group *grp);
71void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node, 71void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node,
72 u32 port, struct sk_buff_head *xmitq); 72 u32 port, struct sk_buff_head *xmitq);
73u16 tipc_group_bc_snd_nxt(struct tipc_group *grp); 73u16 tipc_group_bc_snd_nxt(struct tipc_group *grp);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index d799e50ff722..473a096b6fba 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -116,6 +116,7 @@ struct tipc_sock {
116 struct tipc_mc_method mc_method; 116 struct tipc_mc_method mc_method;
117 struct rcu_head rcu; 117 struct rcu_head rcu;
118 struct tipc_group *group; 118 struct tipc_group *group;
119 bool group_is_open;
119}; 120};
120 121
121static int tipc_sk_backlog_rcv(struct sock *sk, struct sk_buff *skb); 122static int tipc_sk_backlog_rcv(struct sock *sk, struct sk_buff *skb);
@@ -715,7 +716,6 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
715{ 716{
716 struct sock *sk = sock->sk; 717 struct sock *sk = sock->sk;
717 struct tipc_sock *tsk = tipc_sk(sk); 718 struct tipc_sock *tsk = tipc_sk(sk);
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,8 +736,7 @@ 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 grp = tsk->group; 739 if (tsk->group_is_open && !tsk->cong_link_cnt)
740 if ((!grp || tipc_group_is_open(grp)) && !tsk->cong_link_cnt)
741 revents |= POLLOUT; 740 revents |= POLLOUT;
742 if (!tipc_sk_type_connectionless(sk)) 741 if (!tipc_sk_type_connectionless(sk))
743 break; 742 break;
@@ -2758,7 +2757,7 @@ static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq)
2758 return -EINVAL; 2757 return -EINVAL;
2759 if (grp) 2758 if (grp)
2760 return -EACCES; 2759 return -EACCES;
2761 grp = tipc_group_create(net, tsk->portid, mreq); 2760 grp = tipc_group_create(net, tsk->portid, mreq, &tsk->group_is_open);
2762 if (!grp) 2761 if (!grp)
2763 return -ENOMEM; 2762 return -ENOMEM;
2764 tsk->group = grp; 2763 tsk->group = grp;