diff --git a/kmod/src/Makefile.kernelcompat b/kmod/src/Makefile.kernelcompat index 97840bf5..ca408a1a 100644 --- a/kmod/src/Makefile.kernelcompat +++ b/kmod/src/Makefile.kernelcompat @@ -158,3 +158,12 @@ endif ifneq (,$(shell grep 'int...get..const struct xattr_handler.*struct dentry.*dentry,' include/linux/xattr.h)) ccflags-y += -DKC_XATTR_STRUCT_XATTR_HANDLER=1 endif + +# +# v4.16-rc1-1-g9b2c45d479d0 +# +# kernel_getsockname() and kernel_getpeername dropped addrlen arg +# +ifneq (,$(shell grep 'kernel_getsockname.*,$$' include/linux/net.h)) +ccflags-y += -DKC_KERNEL_GETSOCKNAME_ADDRLEN=1 +endif diff --git a/kmod/src/kernelcompat.h b/kmod/src/kernelcompat.h index 2df4ddfe..e3b93c66 100644 --- a/kmod/src/kernelcompat.h +++ b/kmod/src/kernelcompat.h @@ -222,4 +222,34 @@ struct kc_shrinker_wrapper { #endif /* KC_SHRINKER_SHRINK */ +#ifdef KC_KERNEL_GETSOCKNAME_ADDRLEN +#include +#include +static inline int kc_kernel_getsockname(struct socket *sock, struct sockaddr *addr) +{ + int addrlen = sizeof(struct sockaddr_in); + int ret = kernel_getsockname(sock, addr, &addrlen); + if (ret == 0 && addrlen != sizeof(struct sockaddr_in)) + return -EAFNOSUPPORT; + else if (ret < 0) + return ret; + + return sizeof(struct sockaddr_in); +} +static inline int kc_kernel_getpeername(struct socket *sock, struct sockaddr *addr) +{ + int addrlen = sizeof(struct sockaddr_in); + int ret = kernel_getpeername(sock, addr, &addrlen); + if (ret == 0 && addrlen != sizeof(struct sockaddr_in)) + return -EAFNOSUPPORT; + else if (ret < 0) + return ret; + + return sizeof(struct sockaddr_in); +} +#else +#define kc_kernel_getsockname(sock, addr) kernel_getsockname(sock, addr) +#define kc_kernel_getpeername(sock, addr) kernel_getpeername(sock, addr) +#endif + #endif diff --git a/kmod/src/net.c b/kmod/src/net.c index eab190da..c539fde1 100644 --- a/kmod/src/net.c +++ b/kmod/src/net.c @@ -897,7 +897,6 @@ static int sock_opts_and_names(struct scoutfs_net_connection *conn, struct socket *sock) { struct timeval tv; - int addrlen; int optval; int ret; @@ -947,23 +946,18 @@ static int sock_opts_and_names(struct scoutfs_net_connection *conn, if (ret) goto out; - addrlen = sizeof(struct sockaddr_in); - ret = kernel_getsockname(sock, (struct sockaddr *)&conn->sockname, - &addrlen); - if (ret == 0 && addrlen != sizeof(struct sockaddr_in)) - ret = -EAFNOSUPPORT; - if (ret) + ret = kc_kernel_getsockname(sock, (struct sockaddr *)&conn->sockname); + if (ret < 0) goto out; - addrlen = sizeof(struct sockaddr_in); - ret = kernel_getpeername(sock, (struct sockaddr *)&conn->peername, - &addrlen); - if (ret == 0 && addrlen != sizeof(struct sockaddr_in)) - ret = -EAFNOSUPPORT; - if (ret) + ret = kc_kernel_getpeername(sock, (struct sockaddr *)&conn->peername); + if (ret < 0) goto out; + ret = 0; + conn->last_peername = conn->peername; + out: return ret; } @@ -1471,20 +1465,18 @@ int scoutfs_net_bind(struct super_block *sb, goto out; ret = kernel_listen(sock, 255); - if (ret) + if (ret < 0) goto out; - addrlen = sizeof(struct sockaddr_in); - ret = kernel_getsockname(sock, (struct sockaddr *)&conn->sockname, - &addrlen); - if (ret == 0 && addrlen != sizeof(struct sockaddr_in)) - ret = -EAFNOSUPPORT; - if (ret) + ret = kc_kernel_getsockname(sock, (struct sockaddr *)&conn->sockname); + if (ret < 0) goto out; + ret = 0; + conn->sock = sock; *sin = conn->sockname; - ret = 0; + out: if (ret < 0 && sock) sock_release(sock);