Support MSG_TRUNC when passed to recvmsg() as an argument on an AF_NETLINK socket. In such a case, the full size of the packet at the front of the Rx queue should be returned, including any of it discarded when MSG_TRUNC is set by recvmsg() on return.
If MSG_TRUNC is not set, then only the amount of data read into the buffer is returned, and any discarded data goes uncounted. This is according to the recvmsg() manual page. AFS will make use of this feature to work out the buffer size required to receive a netlink message by combining MSG_TRUNC with MSG_PEEK. This feature is useful on netlink sockets as recvmsg() there just discards any of the packet that won't fit in the buffer. Signed-Off-By: David Howells <[EMAIL PROTECTED]> --- net/netlink/af_netlink.c | 15 +++++++++------ 1 files changed, 9 insertions(+), 6 deletions(-) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index e73d8f5..6288dd1 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1194,7 +1194,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, struct sock *sk = sock->sk; struct netlink_sock *nlk = nlk_sk(sk); int noblock = flags&MSG_DONTWAIT; - size_t copied; + size_t copy, copied; struct sk_buff *skb; int err; @@ -1209,14 +1209,17 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, msg->msg_namelen = 0; - copied = skb->len; - if (len < copied) { - msg->msg_flags |= MSG_TRUNC; - copied = len; + copied = copy = skb->len; + if (len < copy) { + copy = len; + if (!(flags & MSG_TRUNC)) { + copied = len; + msg->msg_flags |= MSG_TRUNC; + } } skb->h.raw = skb->data; - err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); + err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copy); if (msg->msg_name) { struct sockaddr_nl *addr = (struct sockaddr_nl*)msg->msg_name; - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html