diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-11-28 15:52:29 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-02-04 01:34:15 -0500 |
commit | f25dcc7687d42a72de18aa41b04990a24c9e77c7 (patch) | |
tree | 37b428117d042baa6cd67333bd9fdf567f85ef47 /net/tipc | |
parent | 21226abb4e9f14d88238964d89b279e461ddc30c (diff) |
tipc: tipc ->sendmsg() conversion
This one needs to copy the same data from user potentially more than
once. Sadly, MTU changes can trigger that ;-/
Cc: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/msg.c | 7 | ||||
-rw-r--r-- | net/tipc/socket.c | 14 |
2 files changed, 14 insertions, 7 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 18aba9e99345..da67c8d3edc6 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -189,7 +189,6 @@ err: | |||
189 | * tipc_msg_build - create buffer chain containing specified header and data | 189 | * tipc_msg_build - create buffer chain containing specified header and data |
190 | * @mhdr: Message header, to be prepended to data | 190 | * @mhdr: Message header, to be prepended to data |
191 | * @m: User message | 191 | * @m: User message |
192 | * @offset: Posision in iov to start copying from | ||
193 | * @dsz: Total length of user data | 192 | * @dsz: Total length of user data |
194 | * @pktmax: Max packet size that can be used | 193 | * @pktmax: Max packet size that can be used |
195 | * @list: Buffer or chain of buffers to be returned to caller | 194 | * @list: Buffer or chain of buffers to be returned to caller |
@@ -221,8 +220,7 @@ int tipc_msg_build(struct net *net, struct tipc_msg *mhdr, struct msghdr *m, | |||
221 | __skb_queue_tail(list, skb); | 220 | __skb_queue_tail(list, skb); |
222 | skb_copy_to_linear_data(skb, mhdr, mhsz); | 221 | skb_copy_to_linear_data(skb, mhdr, mhsz); |
223 | pktpos = skb->data + mhsz; | 222 | pktpos = skb->data + mhsz; |
224 | if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iter.iov, offset, | 223 | if (copy_from_iter(pktpos, dsz, &m->msg_iter) == dsz) |
225 | dsz)) | ||
226 | return dsz; | 224 | return dsz; |
227 | rc = -EFAULT; | 225 | rc = -EFAULT; |
228 | goto error; | 226 | goto error; |
@@ -252,12 +250,11 @@ int tipc_msg_build(struct net *net, struct tipc_msg *mhdr, struct msghdr *m, | |||
252 | if (drem < pktrem) | 250 | if (drem < pktrem) |
253 | pktrem = drem; | 251 | pktrem = drem; |
254 | 252 | ||
255 | if (memcpy_fromiovecend(pktpos, m->msg_iter.iov, offset, pktrem)) { | 253 | if (copy_from_iter(pktpos, pktrem, &m->msg_iter) != pktrem) { |
256 | rc = -EFAULT; | 254 | rc = -EFAULT; |
257 | goto error; | 255 | goto error; |
258 | } | 256 | } |
259 | drem -= pktrem; | 257 | drem -= pktrem; |
260 | offset += pktrem; | ||
261 | 258 | ||
262 | if (!drem) | 259 | if (!drem) |
263 | break; | 260 | break; |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 679a22082fcb..caa4d663fd90 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -733,6 +733,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, | |||
733 | struct net *net = sock_net(sk); | 733 | struct net *net = sock_net(sk); |
734 | struct tipc_msg *mhdr = &tipc_sk(sk)->phdr; | 734 | struct tipc_msg *mhdr = &tipc_sk(sk)->phdr; |
735 | struct sk_buff_head head; | 735 | struct sk_buff_head head; |
736 | struct iov_iter save = msg->msg_iter; | ||
736 | uint mtu; | 737 | uint mtu; |
737 | int rc; | 738 | int rc; |
738 | 739 | ||
@@ -758,8 +759,10 @@ new_mtu: | |||
758 | rc = dsz; | 759 | rc = dsz; |
759 | break; | 760 | break; |
760 | } | 761 | } |
761 | if (rc == -EMSGSIZE) | 762 | if (rc == -EMSGSIZE) { |
763 | msg->msg_iter = save; | ||
762 | goto new_mtu; | 764 | goto new_mtu; |
765 | } | ||
763 | if (rc != -ELINKCONG) | 766 | if (rc != -ELINKCONG) |
764 | break; | 767 | break; |
765 | tipc_sk(sk)->link_cong = 1; | 768 | tipc_sk(sk)->link_cong = 1; |
@@ -895,6 +898,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
895 | struct sk_buff_head head; | 898 | struct sk_buff_head head; |
896 | struct sk_buff *skb; | 899 | struct sk_buff *skb; |
897 | struct tipc_name_seq *seq = &dest->addr.nameseq; | 900 | struct tipc_name_seq *seq = &dest->addr.nameseq; |
901 | struct iov_iter save; | ||
898 | u32 mtu; | 902 | u32 mtu; |
899 | long timeo; | 903 | long timeo; |
900 | int rc; | 904 | int rc; |
@@ -963,6 +967,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
963 | msg_set_hdr_sz(mhdr, BASIC_H_SIZE); | 967 | msg_set_hdr_sz(mhdr, BASIC_H_SIZE); |
964 | } | 968 | } |
965 | 969 | ||
970 | save = m->msg_iter; | ||
966 | new_mtu: | 971 | new_mtu: |
967 | mtu = tipc_node_get_mtu(net, dnode, tsk->portid); | 972 | mtu = tipc_node_get_mtu(net, dnode, tsk->portid); |
968 | __skb_queue_head_init(&head); | 973 | __skb_queue_head_init(&head); |
@@ -980,8 +985,10 @@ new_mtu: | |||
980 | rc = dsz; | 985 | rc = dsz; |
981 | break; | 986 | break; |
982 | } | 987 | } |
983 | if (rc == -EMSGSIZE) | 988 | if (rc == -EMSGSIZE) { |
989 | m->msg_iter = save; | ||
984 | goto new_mtu; | 990 | goto new_mtu; |
991 | } | ||
985 | if (rc != -ELINKCONG) | 992 | if (rc != -ELINKCONG) |
986 | break; | 993 | break; |
987 | tsk->link_cong = 1; | 994 | tsk->link_cong = 1; |
@@ -1052,6 +1059,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, | |||
1052 | long timeo; | 1059 | long timeo; |
1053 | u32 dnode; | 1060 | u32 dnode; |
1054 | uint mtu, send, sent = 0; | 1061 | uint mtu, send, sent = 0; |
1062 | struct iov_iter save; | ||
1055 | 1063 | ||
1056 | /* Handle implied connection establishment */ | 1064 | /* Handle implied connection establishment */ |
1057 | if (unlikely(dest)) { | 1065 | if (unlikely(dest)) { |
@@ -1078,6 +1086,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, | |||
1078 | dnode = tsk_peer_node(tsk); | 1086 | dnode = tsk_peer_node(tsk); |
1079 | 1087 | ||
1080 | next: | 1088 | next: |
1089 | save = m->msg_iter; | ||
1081 | mtu = tsk->max_pkt; | 1090 | mtu = tsk->max_pkt; |
1082 | send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); | 1091 | send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); |
1083 | __skb_queue_head_init(&head); | 1092 | __skb_queue_head_init(&head); |
@@ -1097,6 +1106,7 @@ next: | |||
1097 | if (rc == -EMSGSIZE) { | 1106 | if (rc == -EMSGSIZE) { |
1098 | tsk->max_pkt = tipc_node_get_mtu(net, dnode, | 1107 | tsk->max_pkt = tipc_node_get_mtu(net, dnode, |
1099 | portid); | 1108 | portid); |
1109 | m->msg_iter = save; | ||
1100 | goto next; | 1110 | goto next; |
1101 | } | 1111 | } |
1102 | if (rc != -ELINKCONG) | 1112 | if (rc != -ELINKCONG) |