LINUX 5.8: Replace kernel_setsockopt with new funcs 47/14247/4
authorCheyenne Wills <cwills@sinenomine.net>
Thu, 18 Jun 2020 22:39:22 +0000 (16:39 -0600)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 19 Jun 2020 16:00:28 +0000 (12:00 -0400)
Linux 5.8-rc1 commit 'net: remove kernel_setsockopt' (5a892ff2facb)
retires the kernel_setsockopt function. In prior kernel commits new
functions (ip_sock_set_*) were added to replace the specific functions
performed by kernel_setsockopt.

Define new config test 'HAVE_IP_SOCK_SET' if the 'ip_sock_set' functions
are available. The config define 'HAVE_KERNEL_SETSOCKOPT' is no longer
set in Linux 5.8.

Create wrapper functions that replace the kernel_setsockopt calls with
calls to the appropriate Linux kernel function(s) (depending on what
functions the kernel supports).

Remove the unused 'kernel_getsockopt' function (used for building with
pre 2.6.19 kernels).

For reference
    Linux 2.6.19 introduced kernel_setsockopt
    Linux 5.8 removed kernel_setsockopt and replaced the functionality
              with a set of new functions (ip_sock_set_*)

Change-Id: I517b674303c5decc19313d9de51d04ddef36b421
Reviewed-on: https://gerrit.openafs.org/14247
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

src/afs/LINUX/osi_compat.h
src/cf/linux-kernel-func.m4
src/rx/LINUX/rx_knet.c

index 374e721..a1e7f21 100644 (file)
@@ -314,9 +314,22 @@ zero_user_segment(struct page *pp, unsigned int from1, unsigned int to1)
 }
 #endif
 
-#ifndef HAVE_LINUX_KERNEL_SETSOCKOPT
+#if defined(HAVE_LINUX_IP_SOCK_SET)
+# include <net/ip.h>
+/* ip_sock_set_* introduced in linux 5.8 */
+static inline void
+afs_linux_sock_set_mtu_discover(struct socket *sockp, int pmtu)
+{
+    ip_sock_set_mtu_discover(sockp->sk, pmtu);
+}
+static inline void
+afs_linux_sock_set_recverr(struct socket *sockp)
+{
+    ip_sock_set_recverr(sockp->sk);
+}
+#else
+# if !defined(HAVE_LINUX_KERNEL_SETSOCKOPT)
 /* Available from 2.6.19 */
-
 static inline int
 kernel_setsockopt(struct socket *sockp, int level, int name, char *val,
                  unsigned int len) {
@@ -329,20 +342,22 @@ kernel_setsockopt(struct socket *sockp, int level, int name, char *val,
 
     return ret;
 }
+# endif /* !HAVE_LINUX_KERNEL_SETSOCKOPT */
 
-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->getsockopt(sockp, level, name, val, len);
-    set_fs(old_fs);
-
-    return ret;
+static inline void
+afs_linux_sock_set_mtu_discover(struct socket *sockp, int pmtu)
+{
+    kernel_setsockopt(sockp, SOL_IP, IP_MTU_DISCOVER, (char *)&pmtu,
+                     sizeof(pmtu));
 }
-#endif
+static inline void
+afs_linux_sock_set_recverr(struct socket *sockp)
+{
+    int recverr = 1;
+    kernel_setsockopt(sockp, SOL_IP, IP_RECVERR, (char *)&recverr,
+                     sizeof(recverr));
+}
+#endif /* !HAVE_LINUX_IP_SOCK_SET */
 
 #ifdef HAVE_TRY_TO_FREEZE
 static inline int
index 1d96699..5639bb8 100644 (file)
@@ -154,6 +154,12 @@ AC_CHECK_LINUX_FUNC([lru_cache_add_file],
                     [#include <linux/swap.h>],
                     [lru_cache_add_file(NULL);])
 
+dnl Linux 5.8 replaced kernel_setsockopt with helper functions
+dnl e.g. ip_sock_set_mtu_discover, ip_sock_set_recverr
+AC_CHECK_LINUX_FUNC([ip_sock_set],
+                    [#include <net/ip.h>],
+                    [ip_sock_set_mtu_discover(NULL, 0);])
+
 dnl Consequences - things which get set as a result of the
 dnl                above tests
 AS_IF([test "x$ac_cv_linux_func_d_alloc_anon" = "xno"],
index 9fbb563..50607c8 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/errqueue.h>
 #include <linux/icmp.h>
 #endif
-
 #include "osi_compat.h"
 
 /* rxk_NewSocket
@@ -76,14 +75,10 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport)
        return NULL;
     }
 
-    kernel_setsockopt(sockp, SOL_IP, IP_MTU_DISCOVER, (char *)&pmtu,
-                     sizeof(pmtu));
+    afs_linux_sock_set_mtu_discover(sockp, pmtu);
+
 #ifdef AFS_RXERRQ_ENV
-    {
-       int recverr = 1;
-       kernel_setsockopt(sockp, SOL_IP, IP_RECVERR, (char *)&recverr,
-                         sizeof(recverr));
-    }
+    afs_linux_sock_set_recverr(sockp);
 #endif
     return (osi_socket *)sockp;
 }