Skip to content

Commit

Permalink
net: sendmmsg should only return an error if no messages were sent
Browse files Browse the repository at this point in the history
commit 728ffb8 upstream.

sendmmsg uses a similar error return strategy as recvmmsg but it
turns out to be a confusing way to communicate errors.

The current code stores the error code away and returns it on the next
sendmmsg call. This means a call with completely valid arguments could
get an error from a previous call.

Change things so we only return an error if no datagrams could be sent.
If less than the requested number of messages were sent, the application
must retry starting at the first failed one and if the problem is
persistent the error will be returned.

This matches the behaviour of other syscalls like read/write - it
is not an error if less than the requested number of elements are sent.

Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Anton Blanchard authored and Greg Kroah-Hartman committed Aug 16, 2011
1 parent c82ac94 commit 365f1cd
Showing 1 changed file with 3 additions and 24 deletions.
27 changes: 3 additions & 24 deletions net/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -2005,12 +2005,9 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
if (!sock)
return err;

err = sock_error(sock->sk);
if (err)
goto out_put;

entry = mmsg;
compat_entry = (struct compat_mmsghdr __user *)mmsg;
err = 0;

while (datagrams < vlen) {
/*
Expand All @@ -2037,29 +2034,11 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
++datagrams;
}

out_put:
fput_light(sock->file, fput_needed);

if (err == 0)
return datagrams;

if (datagrams != 0) {
/*
* We may send less entries than requested (vlen) if the
* sock is non blocking...
*/
if (err != -EAGAIN) {
/*
* ... or if sendmsg returns an error after we
* send some datagrams, where we record the
* error to return on the next call or if the
* app asks about it using getsockopt(SO_ERROR).
*/
sock->sk->sk_err = -err;
}

/* We only return an error if no datagrams were able to be sent */
if (datagrams != 0)
return datagrams;
}

return err;
}
Expand Down

0 comments on commit 365f1cd

Please sign in to comment.