aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 291d6bbe85f4..1217c90a363b 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -889,7 +889,6 @@ static int tipc_send_group_unicast(struct socket *sock, struct msghdr *m,
889 DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); 889 DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
890 int blks = tsk_blocks(GROUP_H_SIZE + dlen); 890 int blks = tsk_blocks(GROUP_H_SIZE + dlen);
891 struct tipc_sock *tsk = tipc_sk(sk); 891 struct tipc_sock *tsk = tipc_sk(sk);
892 struct tipc_group *grp = tsk->group;
893 struct net *net = sock_net(sk); 892 struct net *net = sock_net(sk);
894 struct tipc_member *mb = NULL; 893 struct tipc_member *mb = NULL;
895 u32 node, port; 894 u32 node, port;
@@ -903,7 +902,9 @@ static int tipc_send_group_unicast(struct socket *sock, struct msghdr *m,
903 /* Block or return if destination link or member is congested */ 902 /* Block or return if destination link or member is congested */
904 rc = tipc_wait_for_cond(sock, &timeout, 903 rc = tipc_wait_for_cond(sock, &timeout,
905 !tipc_dest_find(&tsk->cong_links, node, 0) && 904 !tipc_dest_find(&tsk->cong_links, node, 0) &&
906 !tipc_group_cong(grp, node, port, blks, &mb)); 905 tsk->group &&
906 !tipc_group_cong(tsk->group, node, port, blks,
907 &mb));
907 if (unlikely(rc)) 908 if (unlikely(rc))
908 return rc; 909 return rc;
909 910
@@ -933,7 +934,6 @@ static int tipc_send_group_anycast(struct socket *sock, struct msghdr *m,
933 struct tipc_sock *tsk = tipc_sk(sk); 934 struct tipc_sock *tsk = tipc_sk(sk);
934 struct list_head *cong_links = &tsk->cong_links; 935 struct list_head *cong_links = &tsk->cong_links;
935 int blks = tsk_blocks(GROUP_H_SIZE + dlen); 936 int blks = tsk_blocks(GROUP_H_SIZE + dlen);
936 struct tipc_group *grp = tsk->group;
937 struct tipc_msg *hdr = &tsk->phdr; 937 struct tipc_msg *hdr = &tsk->phdr;
938 struct tipc_member *first = NULL; 938 struct tipc_member *first = NULL;
939 struct tipc_member *mbr = NULL; 939 struct tipc_member *mbr = NULL;
@@ -950,9 +950,10 @@ static int tipc_send_group_anycast(struct socket *sock, struct msghdr *m,
950 type = msg_nametype(hdr); 950 type = msg_nametype(hdr);
951 inst = dest->addr.name.name.instance; 951 inst = dest->addr.name.name.instance;
952 scope = msg_lookup_scope(hdr); 952 scope = msg_lookup_scope(hdr);
953 exclude = tipc_group_exclude(grp);
954 953
955 while (++lookups < 4) { 954 while (++lookups < 4) {
955 exclude = tipc_group_exclude(tsk->group);
956
956 first = NULL; 957 first = NULL;
957 958
958 /* Look for a non-congested destination member, if any */ 959 /* Look for a non-congested destination member, if any */
@@ -961,7 +962,8 @@ static int tipc_send_group_anycast(struct socket *sock, struct msghdr *m,
961 &dstcnt, exclude, false)) 962 &dstcnt, exclude, false))
962 return -EHOSTUNREACH; 963 return -EHOSTUNREACH;
963 tipc_dest_pop(&dsts, &node, &port); 964 tipc_dest_pop(&dsts, &node, &port);
964 cong = tipc_group_cong(grp, node, port, blks, &mbr); 965 cong = tipc_group_cong(tsk->group, node, port, blks,
966 &mbr);
965 if (!cong) 967 if (!cong)
966 break; 968 break;
967 if (mbr == first) 969 if (mbr == first)
@@ -980,7 +982,8 @@ static int tipc_send_group_anycast(struct socket *sock, struct msghdr *m,
980 /* Block or return if destination link or member is congested */ 982 /* Block or return if destination link or member is congested */
981 rc = tipc_wait_for_cond(sock, &timeout, 983 rc = tipc_wait_for_cond(sock, &timeout,
982 !tipc_dest_find(cong_links, node, 0) && 984 !tipc_dest_find(cong_links, node, 0) &&
983 !tipc_group_cong(grp, node, port, 985 tsk->group &&
986 !tipc_group_cong(tsk->group, node, port,
984 blks, &mbr)); 987 blks, &mbr));
985 if (unlikely(rc)) 988 if (unlikely(rc))
986 return rc; 989 return rc;
@@ -1015,8 +1018,7 @@ static int tipc_send_group_bcast(struct socket *sock, struct msghdr *m,
1015 struct sock *sk = sock->sk; 1018 struct sock *sk = sock->sk;
1016 struct net *net = sock_net(sk); 1019 struct net *net = sock_net(sk);
1017 struct tipc_sock *tsk = tipc_sk(sk); 1020 struct tipc_sock *tsk = tipc_sk(sk);
1018 struct tipc_group *grp = tsk->group; 1021 struct tipc_nlist *dsts;
1019 struct tipc_nlist *dsts = tipc_group_dests(grp);
1020 struct tipc_mc_method *method = &tsk->mc_method; 1022 struct tipc_mc_method *method = &tsk->mc_method;
1021 bool ack = method->mandatory && method->rcast; 1023 bool ack = method->mandatory && method->rcast;
1022 int blks = tsk_blocks(MCAST_H_SIZE + dlen); 1024 int blks = tsk_blocks(MCAST_H_SIZE + dlen);
@@ -1025,15 +1027,17 @@ static int tipc_send_group_bcast(struct socket *sock, struct msghdr *m,
1025 struct sk_buff_head pkts; 1027 struct sk_buff_head pkts;
1026 int rc = -EHOSTUNREACH; 1028 int rc = -EHOSTUNREACH;
1027 1029
1028 if (!dsts->local && !dsts->remote)
1029 return -EHOSTUNREACH;
1030
1031 /* Block or return if any destination link or member is congested */ 1030 /* Block or return if any destination link or member is congested */
1032 rc = tipc_wait_for_cond(sock, &timeout, !tsk->cong_link_cnt && 1031 rc = tipc_wait_for_cond(sock, &timeout,
1033 !tipc_group_bc_cong(grp, blks)); 1032 !tsk->cong_link_cnt && tsk->group &&
1033 !tipc_group_bc_cong(tsk->group, blks));
1034 if (unlikely(rc)) 1034 if (unlikely(rc))
1035 return rc; 1035 return rc;
1036 1036
1037 dsts = tipc_group_dests(tsk->group);
1038 if (!dsts->local && !dsts->remote)
1039 return -EHOSTUNREACH;
1040
1037 /* Complete message header */ 1041 /* Complete message header */
1038 if (dest) { 1042 if (dest) {
1039 msg_set_type(hdr, TIPC_GRP_MCAST_MSG); 1043 msg_set_type(hdr, TIPC_GRP_MCAST_MSG);
@@ -1045,7 +1049,7 @@ static int tipc_send_group_bcast(struct socket *sock, struct msghdr *m,
1045 msg_set_hdr_sz(hdr, GROUP_H_SIZE); 1049 msg_set_hdr_sz(hdr, GROUP_H_SIZE);
1046 msg_set_destport(hdr, 0); 1050 msg_set_destport(hdr, 0);
1047 msg_set_destnode(hdr, 0); 1051 msg_set_destnode(hdr, 0);
1048 msg_set_grp_bc_seqno(hdr, tipc_group_bc_snd_nxt(grp)); 1052 msg_set_grp_bc_seqno(hdr, tipc_group_bc_snd_nxt(tsk->group));
1049 1053
1050 /* Avoid getting stuck with repeated forced replicasts */ 1054 /* Avoid getting stuck with repeated forced replicasts */
1051 msg_set_grp_bc_ack_req(hdr, ack); 1055 msg_set_grp_bc_ack_req(hdr, ack);
@@ -2757,11 +2761,15 @@ void tipc_sk_reinit(struct net *net)
2757 rhashtable_walk_start(&iter); 2761 rhashtable_walk_start(&iter);
2758 2762
2759 while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) { 2763 while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) {
2760 spin_lock_bh(&tsk->sk.sk_lock.slock); 2764 sock_hold(&tsk->sk);
2765 rhashtable_walk_stop(&iter);
2766 lock_sock(&tsk->sk);
2761 msg = &tsk->phdr; 2767 msg = &tsk->phdr;
2762 msg_set_prevnode(msg, tipc_own_addr(net)); 2768 msg_set_prevnode(msg, tipc_own_addr(net));
2763 msg_set_orignode(msg, tipc_own_addr(net)); 2769 msg_set_orignode(msg, tipc_own_addr(net));
2764 spin_unlock_bh(&tsk->sk.sk_lock.slock); 2770 release_sock(&tsk->sk);
2771 rhashtable_walk_start(&iter);
2772 sock_put(&tsk->sk);
2765 } 2773 }
2766 2774
2767 rhashtable_walk_stop(&iter); 2775 rhashtable_walk_stop(&iter);