}
#endif
+#ifndef HAVE_KERNEL_SETSOCKOPT
+/* Available from 2.6.19 */
+
+static inline int
+kernel_setsockopt(struct socket *sockp, int level, int name, char *val,
+ unsigned int len) {
+ mm_segment_t old_fs = get_fs();
+ int ret;
+
+ set_fs(get_ds());
+ ret = sockp->ops->setsockopt(sockp, level, name, val, len);
+ set_fs(old_fs);
+
+ return ret;
+}
+
+static inline int
+kernel_getsockopt(struct socket *sockp, int level, int name, char *val,
+ int *len) {
+ mm_segment_t old_fs = get_fs();
+ int ret;
+
+ set_fs(get_ds());
+ ret = sockp->ops->setsockopt(sockp, level, name, val, len);
+ set_fs(old_fs);
+
+ return ret;
+}
+
+#endif
+
AC_DEFINE([HAVE_VFS_LLSEEK], 1, [define if your kernel has the vfs_llseek function])
fi])
+AC_DEFUN([LINUX_HAVE_KERNEL_SETSOCKOPT], [
+ AC_MSG_CHECKING([for kernel_setsockopt])
+ AC_CACHE_VAL([ac_cv_linux_have_kernel_setsockopt], [
+ AC_TRY_KBUILD(
+[#include <linux/net.h>],
+[kernel_setsockopt(NULL, 0, 0, NULL, 0);],
+ ac_cv_linux_have_kernel_setsockopt=yes,
+ ac_cv_linux_have_kernel_setsockopt=no)])
+ AC_MSG_RESULT($ac_cv_linux_have_kernel_setsockopt)
+ if test "x$ac_cv_linux_have_kernel_setsockopt" = "xyes"; then
+ AC_DEFINE([HAVE_KERNEL_SETSOCKOPT], 1, [define if your kernel has the kernel_setsockopt function])
+ fi])
+
struct socket *sockp;
struct sockaddr_in myaddr;
int code;
- KERNEL_SPACE_DECL;
#ifdef ADAPT_PMTU
int pmtu = IP_PMTUDISC_WANT;
int do_recverr = 1;
return NULL;
}
- TO_USER_SPACE();
- sockp->ops->setsockopt(sockp, SOL_IP, IP_MTU_DISCOVER, (char *)&pmtu,
- sizeof(pmtu));
+ kernel_setsockopt(sockp, SOL_IP, IP_MTU_DISCOVER, (char *)&pmtu,
+ sizeof(pmtu));
#ifdef ADAPT_PMTU
- sockp->ops->setsockopt(sockp, SOL_IP, IP_RECVERR, (char *)&do_recverr,
- sizeof(do_recverr));
+ kernel_setsockopt(sockp, SOL_IP, IP_RECVERR, (char *)&do_recverr,
+ sizeof(do_recverr));
#endif
- TO_KERNEL_SPACE();
return (osi_socket *)sockp;
}
void
handle_socket_error(osi_socket so)
{
- KERNEL_SPACE_DECL;
struct msghdr msg;
struct cmsghdr *cmsg;
struct sock_extended_err *err;
return;
msg.msg_name = &addr;
msg.msg_namelen = sizeof(addr);
- msg.msg_iov = NULL;
- msg.msg_iovlen = 0;
msg.msg_control = controlmsgbuf;
msg.msg_controllen = 256;
msg.msg_flags = 0;
- TO_USER_SPACE();
- code = sock_recvmsg(sop, &msg, 256, MSG_ERRQUEUE|MSG_DONTWAIT|MSG_TRUNC);
- TO_KERNEL_SPACE();
+ code = kernel_recvmsg(sop, &msg, NULL, 0, 256,
+ MSG_ERRQUEUE|MSG_DONTWAIT|MSG_TRUNC);
if (code < 0 || !(msg.msg_flags & MSG_ERRQUEUE))
goto out;
osi_NetSend(osi_socket sop, struct sockaddr_in *to, struct iovec *iovec,
int iovcnt, afs_int32 size, int istack)
{
- KERNEL_SPACE_DECL;
struct msghdr msg;
int code;
#ifdef ADAPT_PMTU
while (1) {
sockerr=0;
esize = sizeof(sockerr);
- TO_USER_SPACE();
- sop->ops->getsockopt(sop, SOL_SOCKET, SO_ERROR, (char *)&sockerr,
- &esize);
- TO_KERNEL_SPACE();
+ kernel_getsockopt(sop, SOL_SOCKET, SO_ERROR, (char *)&sockerr, &esize);
if (sockerr == 0)
break;
handle_socket_error(sop);
}
#endif
- msg.msg_iovlen = iovcnt;
- msg.msg_iov = iovec;
msg.msg_name = to;
msg.msg_namelen = sizeof(*to);
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
- TO_USER_SPACE();
- code = sock_sendmsg(sop, &msg, size);
- TO_KERNEL_SPACE();
+ code = kernel_sendmsg(sop, &msg, (struct kvec *) iovec, iovcnt, size);
return (code < 0) ? code : 0;
}
osi_NetReceive(osi_socket so, struct sockaddr_in *from, struct iovec *iov,
int iovcnt, int *lengthp)
{
- KERNEL_SPACE_DECL;
struct msghdr msg;
int code;
#ifdef ADAPT_PMTU
while (1) {
sockerr=0;
esize = sizeof(sockerr);
- TO_USER_SPACE();
- sop->ops->getsockopt(sop, SOL_SOCKET, SO_ERROR, (char *)&sockerr,
- &esize);
- TO_KERNEL_SPACE();
+ kernel_getsockopt(sop, SOL_SOCKET, SO_ERROR, (char *)&sockerr, &esize);
if (sockerr == 0)
break;
handle_socket_error(so);
msg.msg_controllen = 0;
msg.msg_flags = 0;
- TO_USER_SPACE();
- code = sock_recvmsg(sop, &msg, *lengthp, 0);
- TO_KERNEL_SPACE();
-
+ code = kernel_recvmsg(sop, &msg, (struct kvec *)tmpvec, iovcnt,
+ *lengthp, 0);
if (code < 0) {
#ifdef CONFIG_PM
if (