From: Andrew Deason Date: Wed, 1 Aug 2012 20:31:09 +0000 (-0400) Subject: LINUX: Fix error queue processing X-Git-Tag: openafs-stable-1_8_0pre1~2115 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=407cfd281eab375512881945999b7e13ba93936e;hp=d55df0ac8351b1518d2c3cde6e3938b98b3f21f7 LINUX: Fix error queue processing Receiving error queues in the Linux kernel is a little different from userspace. When we encounter a cmsg that is not CMSG_OK, we need to break out of the loop, and not just continue, since we can keep trying to process the same cmsg over and over. In addition, on successful return, the msg_control buffer has been modified to point to the next available buffer space, and msg_controllen contains how many bytes are remaining. So, we need to adjust the msg_control and msg_controllen values to get something more familiar. Change-Id: I7cc768ea31379915974431d2a3c1fec5e0ac71bb Reviewed-on: http://gerrit.openafs.org/7927 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- diff --git a/src/rx/LINUX/rx_knet.c b/src/rx/LINUX/rx_knet.c index a6a9c23..fdf042e 100644 --- a/src/rx/LINUX/rx_knet.c +++ b/src/rx/LINUX/rx_knet.c @@ -125,9 +125,14 @@ osi_HandleSocketError(osi_socket so) if (code < 0 || !(msg.msg_flags & MSG_ERRQUEUE)) goto out; - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (CMSG_OK(&msg, cmsg) && cmsg->cmsg_level == SOL_IP && - cmsg->cmsg_type == IP_RECVERR) + /* kernel_recvmsg changes msg_control to point at the _end_ of the buffer, + * and msg_controllen is set to the number of bytes remaining */ + msg.msg_controllen = ((char*)msg.msg_control - (char*)controlmsgbuf); + msg.msg_control = controlmsgbuf; + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg && CMSG_OK(&msg, cmsg); + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) break; } if (!cmsg)