diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 40 |
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); |