LINUX 5.8: Replace kernel_setsockopt with new funcs
[openafs.git] / src / afs / LINUX / osi_compat.h
index 2c93d22..a1e7f21 100644 (file)
@@ -222,9 +222,15 @@ afs_linux_search_keyring(afs_ucred_t *cred, struct key_type *type)
     key_ref_t key_ref;
 
     if (afs_session_keyring(cred)) {
+#  if defined(KEYRING_SEARCH_TAKES_RECURSE)
+       key_ref = keyring_search(
+                     make_key_ref(afs_session_keyring(cred), 1),
+                     type, "_pag", 1);
+#  else
        key_ref = keyring_search(
                      make_key_ref(afs_session_keyring(cred), 1),
                      type, "_pag");
+#  endif
        if (IS_ERR(key_ref))
            return ERR_CAST(key_ref);
 
@@ -308,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) {
@@ -323,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
@@ -471,6 +492,33 @@ afs_linux_unlock_inode(struct inode *ip) {
 #endif
 }
 
+/* Use these to lock or unlock an inode for processing
+ * its dentry aliases en masse.
+ */
+#if defined(HAVE_DCACHE_LOCK)
+#define afs_d_alias_lock(ip)       spin_lock(&dcache_lock)
+#define afs_d_alias_unlock(ip)     spin_unlock(&dcache_lock)
+#else
+#define afs_d_alias_lock(ip)       spin_lock(&(ip)->i_lock)
+#define afs_d_alias_unlock(ip)     spin_unlock(&(ip)->i_lock)
+#endif
+
+
+/* Use this instead of dget for dentry operations
+ * that occur under a higher lock (e.g. alias processing).
+ * Requires that the higher lock (e.g. dcache_lock or
+ * inode->i_lock) is already held.
+ */
+static inline void
+afs_linux_dget(struct dentry *dp) {
+#if defined(HAVE_DCACHE_LOCK)
+    dget_locked(dp);
+#else
+    dget(dp);
+#endif
+}
+
+
 static inline int
 afs_inode_setattr(struct osi_file *afile, struct iattr *newattrs) {
 
@@ -594,14 +642,18 @@ afs_truncate(struct inode *inode, int len)
 }
 
 static inline struct proc_dir_entry *
-afs_proc_create(char *name, umode_t mode, struct proc_dir_entry *parent, struct file_operations *fops) {
+#if defined(HAVE_LINUX_STRUCT_PROC_OPS)
+afs_proc_create(char *name, umode_t mode, struct proc_dir_entry *parent, struct proc_ops *ops) {
+#else
+afs_proc_create(char *name, umode_t mode, struct proc_dir_entry *parent, struct file_operations *ops) {
+#endif
 #if defined(HAVE_LINUX_PROC_CREATE)
-    return proc_create(name, mode, parent, fops);
+    return proc_create(name, mode, parent, ops);
 #else
     struct proc_dir_entry *entry;
     entry = create_proc_entry(name, mode, parent);
     if (entry)
-       entry->proc_fops = fops;
+       entry->proc_fops = ops;
     return entry;
 #endif
 }
@@ -685,4 +737,15 @@ afs_file_write(struct file *filp, char __user *buf, size_t len, loff_t *pos)
 #endif
 }
 
+static inline char*
+afs_d_path(struct dentry *dp, struct vfsmount *mnt, char *buf, int buflen)
+{
+#ifdef D_PATH_TAKES_STRUCT_PATH
+    afs_linux_path_t p = { .mnt = mnt, .dentry = dp };
+    return d_path(&p, buf, buflen);
+#else
+    return d_path(dp, mnt, buf, buflen);
+#endif
+}
+
 #endif /* AFS_LINUX_OSI_COMPAT_H */