LINUX 5.6: define osi_timeval32_t for 32-bit Linux
[openafs.git] / src / afs / LINUX / osi_machdep.h
index 520b932..dc7c344 100644 (file)
 #ifndef OSI_MACHDEP_H_
 #define OSI_MACHDEP_H_
 
-#include <linux/version.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4)
-# define AFS_LINUX26_ONEGROUP_ENV 1
-#endif
-
 /* Only needed for xdr.h in glibc 2.1.x */
 #ifndef quad_t
 # define quad_t __quad_t
 
 #define afs_hz HZ
 #include "h/sched.h"
-#if defined(HAVE_LINUX_CURRENT_KERNEL_TIME)
+/* in case cred.h is present but not included in sched.h */
+#if defined(HAVE_LINUX_CRED_H)
+#include "h/cred.h"
+#endif
+
+#if !defined(HAVE_LINUX_TIME_T)
+typedef time64_t time_t;
+#endif
+
+#if defined(HAVE_LINUX_KTIME_GET_COARSE_REAL_TS64)
+static inline time_t osi_Time(void) {
+    struct timespec64 xtime;
+    ktime_get_coarse_real_ts64(&xtime);
+    return xtime.tv_sec;
+}
+#elif defined(HAVE_LINUX_CURRENT_KERNEL_TIME)
 static inline time_t osi_Time(void) {
     struct timespec xtime;
     xtime = current_kernel_time();
@@ -86,9 +96,15 @@ static inline time_t osi_Time(void) {
 # define osi_Time() (xtime.tv_sec)
 #endif
 
-
-
-#ifdef AFS_LINUX_64BIT_KERNEL
+#if defined(HAVE_LINUX_KTIME_GET_REAL_TS64)
+# define osi_GetTime(V)                                      \
+    do {                                                     \
+       struct timespec64 __afs_tv;                          \
+       ktime_get_real_ts64(&__afs_tv);                      \
+       (V)->tv_sec = (afs_int32)__afs_tv.tv_sec;            \
+       (V)->tv_usec = (afs_int32)__afs_tv.tv_nsec / 1000;   \
+    } while(0)
+#elif defined(AFS_LINUX_64BIT_KERNEL) || !defined(HAVE_LINUX_TIME_T)
 # define osi_GetTime(V)                                 \
     do {                                               \
        struct timeval __afs_tv;                              \
@@ -106,7 +122,6 @@ static inline time_t osi_Time(void) {
 #undef gop_lookupname_user
 #define gop_lookupname_user osi_lookupname
 
-#define osi_vnhold(V, N) do { VN_HOLD(AFSTOV(V)); } while (0)
 #define VN_HOLD(V) osi_Assert(igrab((V)) == (V))
 #define VN_RELE(V) iput((V))
 
@@ -124,7 +139,11 @@ wakeup(void *event)
 #define IsAfsVnode(V) ((V)->i_sb == afs_globalVFS)     /* test superblock instead */
 #define SetAfsVnode(V)                                 /* unnecessary */
 
+#if defined(HAVE_LINUX_UACCESS_H)
+#include <linux/uaccess.h>
+#else
 #include <asm/uaccess.h>
+#endif
 
 #define copyin(F, T, C)  (copy_from_user ((char*)(T), (char*)(F), (C)) > 0 ? EFAULT : 0)
 static inline long copyinstr(char *from, char *to, int count, int *length) {
@@ -146,35 +165,84 @@ static inline long copyinstr(char *from, char *to, int count, int *length) {
 #define NGROUPS NGROUPS_SMALL
 #endif
 
+#ifdef STRUCT_GROUP_INFO_HAS_GID
+/* compat macro for Linux 4.9 */
+#define GROUP_AT(gi,x)  ((gi)->gid[x])
+#endif
+
 typedef struct task_struct afs_proc_t;
 
+#ifdef HAVE_LINUX_KUID_T
+
+#include <linux/uidgid.h>
+typedef kuid_t afs_kuid_t;
+typedef kgid_t afs_kgid_t;
+extern struct user_namespace *afs_ns;
+# ifdef CONFIG_USER_NS
+#  define afs_current_user_ns() current_user_ns()
+# else
+/* Here current_user_ns() expands to GPL-only init_user_ns symbol! */
+#  define afs_current_user_ns() ((struct user_namespace *)NULL)
+# endif
+
+static inline kuid_t afs_make_kuid(uid_t uid) {
+    return make_kuid(afs_ns, uid);
+}
+static inline kgid_t afs_make_kgid(gid_t gid) {
+    return make_kgid(afs_ns, gid);
+}
+static inline uid_t afs_from_kuid(kuid_t kuid) {
+    return from_kuid(afs_ns, kuid);
+}
+static inline uid_t afs_from_kgid(kgid_t kgid) {
+    return from_kgid(afs_ns, kgid);
+}
+
+#else
+
+typedef uid_t afs_kuid_t;
+typedef gid_t afs_kgid_t;
+
+static inline afs_kuid_t afs_make_kuid(uid_t uid) {return uid;}
+static inline afs_kgid_t afs_make_kgid(gid_t gid) {return gid;}
+static inline uid_t afs_from_kuid(afs_kuid_t kuid) {return kuid;}
+static inline gid_t afs_from_kgid(afs_kgid_t kgid) {return kgid;}
+static inline unsigned char uid_eq(uid_t a, uid_t b) {return a == b;}
+static inline unsigned char gid_eq(gid_t a, gid_t b) {return a == b;}
+static inline unsigned char uid_lt(uid_t a, uid_t b) {return a < b;}
+static inline unsigned char gid_lt(gid_t a, gid_t b) {return a < b;}
+#define GLOBAL_ROOT_UID ((afs_kuid_t) 0)
+#define GLOBAL_ROOT_GID ((afs_kgid_t) 0)
+
+#endif
+
 /* Credentials.  For newer kernels we use the kernel structure directly. */
 #if defined(STRUCT_TASK_STRUCT_HAS_CRED)
 
 typedef struct cred afs_ucred_t;
 typedef struct cred cred_t;
 
-# define afs_cr_uid(cred) ((cred)->fsuid)
-# define afs_cr_gid(cred) ((cred)->fsgid)
-# define afs_cr_ruid(cred) ((cred)->uid)
-# define afs_cr_rgid(cred) ((cred)->gid)
+# define afs_cr_uid(cred) (afs_from_kuid((cred)->fsuid))
+# define afs_cr_gid(cred) (afs_from_kgid((cred)->fsgid))
+# define afs_cr_ruid(cred) (afs_from_kuid((cred)->uid))
+# define afs_cr_rgid(cred) (afs_from_kgid((cred)->gid))
 # define afs_cr_group_info(cred) ((cred)->group_info)
 # define crhold(c) (get_cred(c))
 static inline void
 afs_set_cr_uid(cred_t *cred, uid_t uid) {
-    cred->fsuid = uid;
+    cred->fsuid = afs_make_kuid(uid);
 }
 static inline void
 afs_set_cr_gid(cred_t *cred, gid_t gid) {
-    cred->fsgid = gid;
+    cred->fsgid = afs_make_kgid(gid);
 }
 static inline void
 afs_set_cr_ruid(cred_t *cred, uid_t uid) {
-    cred->uid = uid;
+    cred->uid = afs_make_kuid(uid);
 }
 static inline void
 afs_set_cr_rgid(cred_t *cred, gid_t gid) {
-    cred->gid = gid;
+    cred->gid = afs_make_kgid(gid);
 }
 static inline void
 afs_set_cr_group_info(cred_t *cred, struct group_info *group_info) {
@@ -184,8 +252,13 @@ afs_set_cr_group_info(cred_t *cred, struct group_info *group_info) {
 # define current_group_info() (current->cred->group_info)
 # define task_gid(task) (task->cred->gid)
 # define task_user(task) (task->cred->user)
-# define task_session_keyring(task) (task->cred->tgcred->session_keyring)
-# define current_session_keyring() (current->cred->tgcred->session_keyring)
+# if defined(STRUCT_CRED_HAS_SESSION_KEYRING)
+#  define task_session_keyring(task) (task->cred->session_keyring)
+#  define current_session_keyring() (current->cred->session_keyring)
+# else
+#  define task_session_keyring(task) (task->cred->tgcred->session_keyring)
+#  define current_session_keyring() (current->cred->tgcred->session_keyring)
+# endif
 
 #else