diff options
author | Ying Xue <ying.xue@windriver.com> | 2015-03-02 02:37:47 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-02 13:06:31 -0500 |
commit | 39a0295f901423e260a034ac7c3211ecaa9c2745 (patch) | |
tree | 8df7aaa52eb02e0253bc49422b628306942ab2f2 | |
parent | 6556c38524f3a55427598af2d7fc9c1d9c75bdae (diff) |
tipc: Don't use iocb argument in socket layer
Currently the iocb argument is used to idenfiy whether or not socket
lock is hold before tipc_sendmsg()/tipc_send_stream() is called. But
this usage prevents iocb argument from being dropped through sendmsg()
at socket common layer. Therefore, in the commit we introduce two new
functions called __tipc_sendmsg() and __tipc_send_stream(). When they
are invoked, it assumes that their callers have taken socket lock,
thereby avoiding the weird usage of iocb argument.
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/tipc/socket.c | 82 |
1 files changed, 44 insertions, 38 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index f73e975af80b..c245ec31fa4c 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -114,6 +114,9 @@ static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, | |||
114 | static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid); | 114 | static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid); |
115 | static int tipc_sk_insert(struct tipc_sock *tsk); | 115 | static int tipc_sk_insert(struct tipc_sock *tsk); |
116 | static void tipc_sk_remove(struct tipc_sock *tsk); | 116 | static void tipc_sk_remove(struct tipc_sock *tsk); |
117 | static int __tipc_send_stream(struct socket *sock, struct msghdr *m, | ||
118 | size_t dsz); | ||
119 | static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz); | ||
117 | 120 | ||
118 | static const struct proto_ops packet_ops; | 121 | static const struct proto_ops packet_ops; |
119 | static const struct proto_ops stream_ops; | 122 | static const struct proto_ops stream_ops; |
@@ -907,6 +910,18 @@ static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p) | |||
907 | static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | 910 | static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, |
908 | struct msghdr *m, size_t dsz) | 911 | struct msghdr *m, size_t dsz) |
909 | { | 912 | { |
913 | struct sock *sk = sock->sk; | ||
914 | int ret; | ||
915 | |||
916 | lock_sock(sk); | ||
917 | ret = __tipc_sendmsg(sock, m, dsz); | ||
918 | release_sock(sk); | ||
919 | |||
920 | return ret; | ||
921 | } | ||
922 | |||
923 | static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz) | ||
924 | { | ||
910 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); | 925 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); |
911 | struct sock *sk = sock->sk; | 926 | struct sock *sk = sock->sk; |
912 | struct tipc_sock *tsk = tipc_sk(sk); | 927 | struct tipc_sock *tsk = tipc_sk(sk); |
@@ -931,22 +946,13 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
931 | if (dsz > TIPC_MAX_USER_MSG_SIZE) | 946 | if (dsz > TIPC_MAX_USER_MSG_SIZE) |
932 | return -EMSGSIZE; | 947 | return -EMSGSIZE; |
933 | 948 | ||
934 | if (iocb) | ||
935 | lock_sock(sk); | ||
936 | |||
937 | if (unlikely(sock->state != SS_READY)) { | 949 | if (unlikely(sock->state != SS_READY)) { |
938 | if (sock->state == SS_LISTENING) { | 950 | if (sock->state == SS_LISTENING) |
939 | rc = -EPIPE; | 951 | return -EPIPE; |
940 | goto exit; | 952 | if (sock->state != SS_UNCONNECTED) |
941 | } | 953 | return -EISCONN; |
942 | if (sock->state != SS_UNCONNECTED) { | 954 | if (tsk->published) |
943 | rc = -EISCONN; | 955 | return -EOPNOTSUPP; |
944 | goto exit; | ||
945 | } | ||
946 | if (tsk->published) { | ||
947 | rc = -EOPNOTSUPP; | ||
948 | goto exit; | ||
949 | } | ||
950 | if (dest->addrtype == TIPC_ADDR_NAME) { | 956 | if (dest->addrtype == TIPC_ADDR_NAME) { |
951 | tsk->conn_type = dest->addr.name.name.type; | 957 | tsk->conn_type = dest->addr.name.name.type; |
952 | tsk->conn_instance = dest->addr.name.name.instance; | 958 | tsk->conn_instance = dest->addr.name.name.instance; |
@@ -956,8 +962,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
956 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); | 962 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); |
957 | 963 | ||
958 | if (dest->addrtype == TIPC_ADDR_MCAST) { | 964 | if (dest->addrtype == TIPC_ADDR_MCAST) { |
959 | rc = tipc_sendmcast(sock, seq, m, dsz, timeo); | 965 | return tipc_sendmcast(sock, seq, m, dsz, timeo); |
960 | goto exit; | ||
961 | } else if (dest->addrtype == TIPC_ADDR_NAME) { | 966 | } else if (dest->addrtype == TIPC_ADDR_NAME) { |
962 | u32 type = dest->addr.name.name.type; | 967 | u32 type = dest->addr.name.name.type; |
963 | u32 inst = dest->addr.name.name.instance; | 968 | u32 inst = dest->addr.name.name.instance; |
@@ -972,10 +977,8 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
972 | dport = tipc_nametbl_translate(net, type, inst, &dnode); | 977 | dport = tipc_nametbl_translate(net, type, inst, &dnode); |
973 | msg_set_destnode(mhdr, dnode); | 978 | msg_set_destnode(mhdr, dnode); |
974 | msg_set_destport(mhdr, dport); | 979 | msg_set_destport(mhdr, dport); |
975 | if (unlikely(!dport && !dnode)) { | 980 | if (unlikely(!dport && !dnode)) |
976 | rc = -EHOSTUNREACH; | 981 | return -EHOSTUNREACH; |
977 | goto exit; | ||
978 | } | ||
979 | } else if (dest->addrtype == TIPC_ADDR_ID) { | 982 | } else if (dest->addrtype == TIPC_ADDR_ID) { |
980 | dnode = dest->addr.id.node; | 983 | dnode = dest->addr.id.node; |
981 | msg_set_type(mhdr, TIPC_DIRECT_MSG); | 984 | msg_set_type(mhdr, TIPC_DIRECT_MSG); |
@@ -990,7 +993,7 @@ new_mtu: | |||
990 | mtu = tipc_node_get_mtu(net, dnode, tsk->portid); | 993 | mtu = tipc_node_get_mtu(net, dnode, tsk->portid); |
991 | rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, pktchain); | 994 | rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, pktchain); |
992 | if (rc < 0) | 995 | if (rc < 0) |
993 | goto exit; | 996 | return rc; |
994 | 997 | ||
995 | do { | 998 | do { |
996 | skb = skb_peek(pktchain); | 999 | skb = skb_peek(pktchain); |
@@ -1013,9 +1016,6 @@ new_mtu: | |||
1013 | if (rc) | 1016 | if (rc) |
1014 | __skb_queue_purge(pktchain); | 1017 | __skb_queue_purge(pktchain); |
1015 | } while (!rc); | 1018 | } while (!rc); |
1016 | exit: | ||
1017 | if (iocb) | ||
1018 | release_sock(sk); | ||
1019 | 1019 | ||
1020 | return rc; | 1020 | return rc; |
1021 | } | 1021 | } |
@@ -1066,6 +1066,18 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, | |||
1066 | struct msghdr *m, size_t dsz) | 1066 | struct msghdr *m, size_t dsz) |
1067 | { | 1067 | { |
1068 | struct sock *sk = sock->sk; | 1068 | struct sock *sk = sock->sk; |
1069 | int ret; | ||
1070 | |||
1071 | lock_sock(sk); | ||
1072 | ret = __tipc_send_stream(sock, m, dsz); | ||
1073 | release_sock(sk); | ||
1074 | |||
1075 | return ret; | ||
1076 | } | ||
1077 | |||
1078 | static int __tipc_send_stream(struct socket *sock, struct msghdr *m, size_t dsz) | ||
1079 | { | ||
1080 | struct sock *sk = sock->sk; | ||
1069 | struct net *net = sock_net(sk); | 1081 | struct net *net = sock_net(sk); |
1070 | struct tipc_sock *tsk = tipc_sk(sk); | 1082 | struct tipc_sock *tsk = tipc_sk(sk); |
1071 | struct tipc_msg *mhdr = &tsk->phdr; | 1083 | struct tipc_msg *mhdr = &tsk->phdr; |
@@ -1080,7 +1092,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, | |||
1080 | 1092 | ||
1081 | /* Handle implied connection establishment */ | 1093 | /* Handle implied connection establishment */ |
1082 | if (unlikely(dest)) { | 1094 | if (unlikely(dest)) { |
1083 | rc = tipc_sendmsg(iocb, sock, m, dsz); | 1095 | rc = __tipc_sendmsg(sock, m, dsz); |
1084 | if (dsz && (dsz == rc)) | 1096 | if (dsz && (dsz == rc)) |
1085 | tsk->sent_unacked = 1; | 1097 | tsk->sent_unacked = 1; |
1086 | return rc; | 1098 | return rc; |
@@ -1088,15 +1100,11 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, | |||
1088 | if (dsz > (uint)INT_MAX) | 1100 | if (dsz > (uint)INT_MAX) |
1089 | return -EMSGSIZE; | 1101 | return -EMSGSIZE; |
1090 | 1102 | ||
1091 | if (iocb) | ||
1092 | lock_sock(sk); | ||
1093 | |||
1094 | if (unlikely(sock->state != SS_CONNECTED)) { | 1103 | if (unlikely(sock->state != SS_CONNECTED)) { |
1095 | if (sock->state == SS_DISCONNECTING) | 1104 | if (sock->state == SS_DISCONNECTING) |
1096 | rc = -EPIPE; | 1105 | return -EPIPE; |
1097 | else | 1106 | else |
1098 | rc = -ENOTCONN; | 1107 | return -ENOTCONN; |
1099 | goto exit; | ||
1100 | } | 1108 | } |
1101 | 1109 | ||
1102 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); | 1110 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); |
@@ -1108,7 +1116,7 @@ next: | |||
1108 | send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); | 1116 | send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); |
1109 | rc = tipc_msg_build(mhdr, m, sent, send, mtu, pktchain); | 1117 | rc = tipc_msg_build(mhdr, m, sent, send, mtu, pktchain); |
1110 | if (unlikely(rc < 0)) | 1118 | if (unlikely(rc < 0)) |
1111 | goto exit; | 1119 | return rc; |
1112 | do { | 1120 | do { |
1113 | if (likely(!tsk_conn_cong(tsk))) { | 1121 | if (likely(!tsk_conn_cong(tsk))) { |
1114 | rc = tipc_link_xmit(net, pktchain, dnode, portid); | 1122 | rc = tipc_link_xmit(net, pktchain, dnode, portid); |
@@ -1133,9 +1141,7 @@ next: | |||
1133 | if (rc) | 1141 | if (rc) |
1134 | __skb_queue_purge(pktchain); | 1142 | __skb_queue_purge(pktchain); |
1135 | } while (!rc); | 1143 | } while (!rc); |
1136 | exit: | 1144 | |
1137 | if (iocb) | ||
1138 | release_sock(sk); | ||
1139 | return sent ? sent : rc; | 1145 | return sent ? sent : rc; |
1140 | } | 1146 | } |
1141 | 1147 | ||
@@ -1947,7 +1953,7 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest, | |||
1947 | if (!timeout) | 1953 | if (!timeout) |
1948 | m.msg_flags = MSG_DONTWAIT; | 1954 | m.msg_flags = MSG_DONTWAIT; |
1949 | 1955 | ||
1950 | res = tipc_sendmsg(NULL, sock, &m, 0); | 1956 | res = __tipc_sendmsg(sock, &m, 0); |
1951 | if ((res < 0) && (res != -EWOULDBLOCK)) | 1957 | if ((res < 0) && (res != -EWOULDBLOCK)) |
1952 | goto exit; | 1958 | goto exit; |
1953 | 1959 | ||
@@ -2103,7 +2109,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) | |||
2103 | struct msghdr m = {NULL,}; | 2109 | struct msghdr m = {NULL,}; |
2104 | 2110 | ||
2105 | tsk_advance_rx_queue(sk); | 2111 | tsk_advance_rx_queue(sk); |
2106 | tipc_send_packet(NULL, new_sock, &m, 0); | 2112 | __tipc_send_stream(new_sock, &m, 0); |
2107 | } else { | 2113 | } else { |
2108 | __skb_dequeue(&sk->sk_receive_queue); | 2114 | __skb_dequeue(&sk->sk_receive_queue); |
2109 | __skb_queue_head(&new_sk->sk_receive_queue, buf); | 2115 | __skb_queue_head(&new_sk->sk_receive_queue, buf); |