Skip to content

Commit

Permalink
tipc: tipc ->sendmsg() conversion
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Al Viro committed Feb 4, 2015
1 parent 21226ab commit f25dcc7
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 7 deletions.
7 changes: 2 additions & 5 deletions net/tipc/msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
* tipc_msg_build - create buffer chain containing specified header and data
* @mhdr: Message header, to be prepended to data
* @m: User message
* @offset: Posision in iov to start copying from
* @dsz: Total length of user data
* @pktmax: Max packet size that can be used
* @list: Buffer or chain of buffers to be returned to caller
Expand Down Expand Up @@ -221,8 +220,7 @@ int tipc_msg_build(struct net *net, struct tipc_msg *mhdr, struct msghdr *m,
__skb_queue_tail(list, skb);
skb_copy_to_linear_data(skb, mhdr, mhsz);
pktpos = skb->data + mhsz;
if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iter.iov, offset,
dsz))
if (copy_from_iter(pktpos, dsz, &m->msg_iter) == dsz)
return dsz;
rc = -EFAULT;
goto error;
Expand Down Expand Up @@ -252,12 +250,11 @@ int tipc_msg_build(struct net *net, struct tipc_msg *mhdr, struct msghdr *m,
if (drem < pktrem)
pktrem = drem;

if (memcpy_fromiovecend(pktpos, m->msg_iter.iov, offset, pktrem)) {
if (copy_from_iter(pktpos, pktrem, &m->msg_iter) != pktrem) {
rc = -EFAULT;
goto error;
}
drem -= pktrem;
offset += pktrem;

if (!drem)
break;
Expand Down
14 changes: 12 additions & 2 deletions net/tipc/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
struct net *net = sock_net(sk);
struct tipc_msg *mhdr = &tipc_sk(sk)->phdr;
struct sk_buff_head head;
struct iov_iter save = msg->msg_iter;
uint mtu;
int rc;

Expand All @@ -758,8 +759,10 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
rc = dsz;
break;
}
if (rc == -EMSGSIZE)
if (rc == -EMSGSIZE) {
msg->msg_iter = save;
goto new_mtu;
}
if (rc != -ELINKCONG)
break;
tipc_sk(sk)->link_cong = 1;
Expand Down Expand Up @@ -895,6 +898,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
struct sk_buff_head head;
struct sk_buff *skb;
struct tipc_name_seq *seq = &dest->addr.nameseq;
struct iov_iter save;
u32 mtu;
long timeo;
int rc;
Expand Down Expand Up @@ -963,6 +967,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
msg_set_hdr_sz(mhdr, BASIC_H_SIZE);
}

save = m->msg_iter;
new_mtu:
mtu = tipc_node_get_mtu(net, dnode, tsk->portid);
__skb_queue_head_init(&head);
Expand All @@ -980,8 +985,10 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
rc = dsz;
break;
}
if (rc == -EMSGSIZE)
if (rc == -EMSGSIZE) {
m->msg_iter = save;
goto new_mtu;
}
if (rc != -ELINKCONG)
break;
tsk->link_cong = 1;
Expand Down Expand Up @@ -1052,6 +1059,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
long timeo;
u32 dnode;
uint mtu, send, sent = 0;
struct iov_iter save;

/* Handle implied connection establishment */
if (unlikely(dest)) {
Expand All @@ -1078,6 +1086,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
dnode = tsk_peer_node(tsk);

next:
save = m->msg_iter;
mtu = tsk->max_pkt;
send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE);
__skb_queue_head_init(&head);
Expand All @@ -1097,6 +1106,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
if (rc == -EMSGSIZE) {
tsk->max_pkt = tipc_node_get_mtu(net, dnode,
portid);
m->msg_iter = save;
goto next;
}
if (rc != -ELINKCONG)
Expand Down

0 comments on commit f25dcc7

Please sign in to comment.