Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / afs / LINUX / osi_machdep.h
CommitLineData
805e021f
CE
1/*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10/*
11 * Linux implementation.
12 *
13 */
14
15#ifndef OSI_MACHDEP_H_
16#define OSI_MACHDEP_H_
17
18/* Only needed for xdr.h in glibc 2.1.x */
19#ifndef quad_t
20# define quad_t __quad_t
21# define u_quad_t __u_quad_t
22#endif
23
24#undef getuerror
25
26#ifdef STRUCT_TASK_STRUCT_HAS_TGID
27# define getpid() current->tgid
28# ifdef STRUCT_TASK_STRUCT_HAS_REAL_PARENT
29# define getppid() current->real_parent->tgid
30# elif defined(STRUCT_TASK_STRUCT_HAS_PARENT)
31# define getppid() current->parent->tgid
32# else
33# define getppid() current->p_opptr->tgid
34# endif
35#else /* !STRUCT_TASK_STRUCT_HAS_TGID */
36# define getpid() current->pid
37# ifdef STRUCT_TASK_STRUCT_HAS_REAL_PARENT
38# define getppid() current->real_parent->pid
39# elif defined(STRUCT_TASK_STRUCT_HAS_PARENT)
40# define getppid() current->parent->pid
41# else
42# define getppid() current->p_opptr->pid
43# endif
44#endif /* STRUCT_TASK_STRUCT_HAS_TGID */
45
46#ifdef RECALC_SIGPENDING_TAKES_VOID
47# define RECALC_SIGPENDING(X) recalc_sigpending()
48#else
49# define RECALC_SIGPENDING(X) recalc_sigpending(X)
50#endif
51
52#if defined (STRUCT_TASK_STRUCT_HAS_SIGMASK_LOCK)
53# define SIG_LOCK(X) spin_lock_irq(&X->sigmask_lock)
54# define SIG_UNLOCK(X) spin_unlock_irq(&X->sigmask_lock)
55#elif defined (STRUCT_TASK_STRUCT_HAS_SIGHAND)
56# define SIG_LOCK(X) spin_lock_irq(&X->sighand->siglock)
57# define SIG_UNLOCK(X) spin_unlock_irq(&X->sighand->siglock)
58#else
59# define SIG_LOCK(X) spin_lock_irq(&X->sig->siglock)
60# define SIG_UNLOCK(X) spin_unlock_irq(&X->sig->siglock)
61#endif
62
63#if defined (STRUCT_TASK_STRUCT_HAS_RLIM)
64# define TASK_STRUCT_RLIM rlim
65#elif defined (STRUCT_TASK_STRUCT_HAS_SIGNAL_RLIM)
66# define TASK_STRUCT_RLIM signal->rlim
67#else
68# error Not sure what to do about rlim (should be in the Linux task struct somewhere....)
69#endif
70
71
72#define afs_hz HZ
73#include "h/sched.h"
74/* in case cred.h is present but not included in sched.h */
75#if defined(HAVE_LINUX_CRED_H)
76#include "h/cred.h"
77#endif
78
79#if defined(HAVE_LINUX_KTIME_GET_COARSE_REAL_TS64)
80static inline time_t osi_Time(void) {
81 struct timespec64 xtime;
82 ktime_get_coarse_real_ts64(&xtime);
83 return xtime.tv_sec;
84}
85#elif defined(HAVE_LINUX_CURRENT_KERNEL_TIME)
86static inline time_t osi_Time(void) {
87 struct timespec xtime;
88 xtime = current_kernel_time();
89 return xtime.tv_sec;
90}
91#else
92# define osi_Time() (xtime.tv_sec)
93#endif
94
95#if defined(HAVE_LINUX_KTIME_GET_REAL_TS64)
96# define osi_GetTime(V) \
97 do { \
98 struct timespec64 __afs_tv; \
99 ktime_get_real_ts64(&__afs_tv); \
100 (V)->tv_sec = (afs_int32)__afs_tv.tv_sec; \
101 (V)->tv_usec = (afs_int32)__afs_tv.tv_nsec / 1000; \
102 } while(0)
103#elif defined(AFS_LINUX_64BIT_KERNEL)
104# define osi_GetTime(V) \
105 do { \
106 struct timeval __afs_tv; \
107 do_gettimeofday(&__afs_tv); \
108 (V)->tv_sec = (afs_int32)__afs_tv.tv_sec; \
109 (V)->tv_usec = (afs_int32)__afs_tv.tv_usec; \
110 } while (0)
111#else
112# define osi_GetTime(V) do_gettimeofday((V))
113#endif
114
115#undef gop_lookupname
116#define gop_lookupname osi_lookupname
117
118#undef gop_lookupname_user
119#define gop_lookupname_user osi_lookupname
120
121#define osi_vnhold(V, N) do { VN_HOLD(AFSTOV(V)); } while (0)
122#define VN_HOLD(V) osi_Assert(igrab((V)) == (V))
123#define VN_RELE(V) iput((V))
124
125#define afs_suser(x) capable(CAP_SYS_ADMIN)
126extern int afs_osi_Wakeup(void *event);
127static inline void
128wakeup(void *event)
129{
130 afs_osi_Wakeup(event);
131}
132
133#define vType(V) ((AFSTOV((V)))->i_mode & S_IFMT)
134#define vSetType(V, type) AFSTOV((V))->i_mode = ((type) | (AFSTOV((V))->i_mode & ~S_IFMT)) /* preserve mode */
135#define vSetVfsp(V, vfsp) /* unused */
136#define IsAfsVnode(V) ((V)->i_sb == afs_globalVFS) /* test superblock instead */
137#define SetAfsVnode(V) /* unnecessary */
138
139#if defined(HAVE_LINUX_UACCESS_H)
140#include <linux/uaccess.h>
141#else
142#include <asm/uaccess.h>
143#endif
144
145#define copyin(F, T, C) (copy_from_user ((char*)(T), (char*)(F), (C)) > 0 ? EFAULT : 0)
146static inline long copyinstr(char *from, char *to, int count, int *length) {
147 long tmp;
148 tmp = strncpy_from_user(to, from, count);
149 if (tmp < 0)
150 return EFAULT;
151 *length = tmp;
152 return 0;
153}
154#define copyout(F, T, C) (copy_to_user ((char*)(T), (char*)(F), (C)) > 0 ? EFAULT : 0)
155
156/* kernel print statements */
157#define printf(args...) printk(args)
158#define uprintf(args...) printk(args)
159
160
161#ifndef NGROUPS
162#define NGROUPS NGROUPS_SMALL
163#endif
164
165#ifdef STRUCT_GROUP_INFO_HAS_GID
166/* compat macro for Linux 4.9 */
167#define GROUP_AT(gi,x) ((gi)->gid[x])
168#endif
169
170typedef struct task_struct afs_proc_t;
171
172#ifdef HAVE_LINUX_KUID_T
173
174#include <linux/uidgid.h>
175typedef kuid_t afs_kuid_t;
176typedef kgid_t afs_kgid_t;
177extern struct user_namespace *afs_ns;
178# ifdef CONFIG_USER_NS
179# define afs_current_user_ns() current_user_ns()
180# else
181/* Here current_user_ns() expands to GPL-only init_user_ns symbol! */
182# define afs_current_user_ns() ((struct user_namespace *)NULL)
183# endif
184
185static inline kuid_t afs_make_kuid(uid_t uid) {
186 return make_kuid(afs_ns, uid);
187}
188static inline kgid_t afs_make_kgid(gid_t gid) {
189 return make_kgid(afs_ns, gid);
190}
191static inline uid_t afs_from_kuid(kuid_t kuid) {
192 return from_kuid(afs_ns, kuid);
193}
194static inline uid_t afs_from_kgid(kgid_t kgid) {
195 return from_kgid(afs_ns, kgid);
196}
197
198#else
199
200typedef uid_t afs_kuid_t;
201typedef gid_t afs_kgid_t;
202
203static inline afs_kuid_t afs_make_kuid(uid_t uid) {return uid;}
204static inline afs_kgid_t afs_make_kgid(gid_t gid) {return gid;}
205static inline uid_t afs_from_kuid(afs_kuid_t kuid) {return kuid;}
206static inline gid_t afs_from_kgid(afs_kgid_t kgid) {return kgid;}
207static inline unsigned char uid_eq(uid_t a, uid_t b) {return a == b;}
208static inline unsigned char gid_eq(gid_t a, gid_t b) {return a == b;}
209static inline unsigned char uid_lt(uid_t a, uid_t b) {return a < b;}
210static inline unsigned char gid_lt(gid_t a, gid_t b) {return a < b;}
211#define GLOBAL_ROOT_UID ((afs_kuid_t) 0)
212#define GLOBAL_ROOT_GID ((afs_kgid_t) 0)
213
214#endif
215
216/* Credentials. For newer kernels we use the kernel structure directly. */
217#if defined(STRUCT_TASK_STRUCT_HAS_CRED)
218
219typedef struct cred afs_ucred_t;
220typedef struct cred cred_t;
221
222# define afs_cr_uid(cred) (afs_from_kuid((cred)->fsuid))
223# define afs_cr_gid(cred) (afs_from_kgid((cred)->fsgid))
224# define afs_cr_ruid(cred) (afs_from_kuid((cred)->uid))
225# define afs_cr_rgid(cred) (afs_from_kgid((cred)->gid))
226# define afs_cr_group_info(cred) ((cred)->group_info)
227# define crhold(c) (get_cred(c))
228static inline void
229afs_set_cr_uid(cred_t *cred, uid_t uid) {
230 cred->fsuid = afs_make_kuid(uid);
231}
232static inline void
233afs_set_cr_gid(cred_t *cred, gid_t gid) {
234 cred->fsgid = afs_make_kgid(gid);
235}
236static inline void
237afs_set_cr_ruid(cred_t *cred, uid_t uid) {
238 cred->uid = afs_make_kuid(uid);
239}
240static inline void
241afs_set_cr_rgid(cred_t *cred, gid_t gid) {
242 cred->gid = afs_make_kgid(gid);
243}
244static inline void
245afs_set_cr_group_info(cred_t *cred, struct group_info *group_info) {
246 cred->group_info = group_info;
247}
248
249# define current_group_info() (current->cred->group_info)
250# define task_gid(task) (task->cred->gid)
251# define task_user(task) (task->cred->user)
252# if defined(STRUCT_CRED_HAS_SESSION_KEYRING)
253# define task_session_keyring(task) (task->cred->session_keyring)
254# define current_session_keyring() (current->cred->session_keyring)
255# else
256# define task_session_keyring(task) (task->cred->tgcred->session_keyring)
257# define current_session_keyring() (current->cred->tgcred->session_keyring)
258# endif
259
260#else
261
262typedef struct afs_cred {
263 atomic_t cr_ref;
264 uid_t cr_uid;
265 uid_t cr_ruid;
266 gid_t cr_gid;
267 gid_t cr_rgid;
268 struct group_info *cr_group_info;
269} cred_t;
270
271typedef struct afs_cred afs_ucred_t;
272# define afs_cr_group_info(cred) ((cred)->cr_group_info)
273static inline void
274afs_set_cr_group_info(cred_t *cred, struct group_info *group_info) {
275 cred->cr_group_info = group_info;
276}
277
278# define current_group_info() (current->group_info)
279# if !defined(task_gid)
280# define task_gid(task) (task->gid)
281# endif
282# if !defined(task_uid)
283# define task_uid(task) (task->uid)
284# endif
285# define task_user(task) (task->user)
286# define task_session_keyring(task) (task->signal->session_keyring)
287# define current_session_keyring() (current->signal->session_keyring)
288# define crhold(c) atomic_inc(&(c)->cr_ref)
289
290#endif /* defined(STRUCT_TASK_STRUCT_HAS_CRED) */
291
292#if !defined(current_cred)
293# define current_gid() (current->gid)
294# define current_uid() (current->uid)
295# define current_fsgid() (current->fsgid)
296# define current_fsuid() (current->fsuid)
297#endif
298
299/* UIO manipulation */
300typedef enum { AFS_UIOSYS, AFS_UIOUSER } uio_seg_t;
301typedef enum { UIO_READ, UIO_WRITE } uio_flag_t;
302struct uio {
303 struct iovec *uio_iov;
304 int uio_iovcnt;
305 afs_offs_t uio_offset;
306 uio_seg_t uio_seg;
307 int uio_resid;
308 uio_flag_t uio_flag;
309};
310#define afsio_iov uio_iov
311#define afsio_iovcnt uio_iovcnt
312#define afsio_offset uio_offset
313#define afsio_seg uio_segflg
314#define afsio_fmode uio_fmode
315#define afsio_resid uio_resid
316
317/* Get/set the inode in the osifile struct. */
318#define FILE_INODE(F) (F)->f_dentry->d_inode
319
320#define OSIFILE_INODE(a) FILE_INODE((a)->filp)
321
322#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
323# define NEED_IOCTL32
324#endif
325
326#include <linux/version.h>
327#include <linux/sched.h>
328#include <linux/wait.h>
329
330#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
331extern struct mutex afs_global_lock;
332#else
333extern struct semaphore afs_global_lock;
334# define mutex_lock(lock) down(lock)
335# define mutex_unlock(lock) up(lock)
336#endif
337extern int afs_global_owner;
338
339#define AFS_GLOCK() \
340do { \
341 mutex_lock(&afs_global_lock); \
342 if (afs_global_owner) \
343 osi_Panic("afs_global_lock already held by pid %d", \
344 afs_global_owner); \
345 afs_global_owner = current->pid; \
346} while (0)
347
348#define ISAFS_GLOCK() (afs_global_owner == current->pid)
349
350#define AFS_GUNLOCK() \
351do { \
352 if (!ISAFS_GLOCK()) \
353 osi_Panic("afs global lock not held at %s:%d", __FILE__, __LINE__); \
354 afs_global_owner = 0; \
355 mutex_unlock(&afs_global_lock); \
356} while (0)
357
358#define osi_InitGlock()
359
360#ifdef AFS_AMD64_LINUX20_ENV
361/* RHEL5 beta's kernel doesn't define these. They aren't gonna change, so... */
362
363# ifndef __NR_ia32_afs_syscall
364# define __NR_ia32_afs_syscall 137
365# endif
366# ifndef __NR_ia32_setgroups
367# define __NR_ia32_setgroups 81
368# endif
369# ifndef __NR_ia32_setgroups32
370# define __NR_ia32_setgroups32 206
371# endif
372# ifndef __NR_ia32_close
373# define __NR_ia32_close 6
374# endif
375# ifndef __NR_ia32_chdir
376# define __NR_ia32_chdir 12
377# endif
378# ifndef __NR_ia32_break
379# define __NR_ia32_break 17
380# endif
381# ifndef __NR_ia32_stty
382# define __NR_ia32_stty 31
383# endif
384# ifndef __NR_ia32_gtty
385# define __NR_ia32_gtty 32
386# endif
387# ifndef __NR_ia32_ftime
388# define __NR_ia32_ftime 35
389# endif
390# ifndef __NR_ia32_prof
391# define __NR_ia32_prof 44
392# endif
393# ifndef __NR_ia32_lock
394# define __NR_ia32_lock 53
395# endif
396# ifndef __NR_ia32_mpx
397# define __NR_ia32_mpx 56
398# endif
399# ifndef __NR_ia32_exit
400# define __NR_ia32_exit 1
401# endif
402# ifndef __NR_ia32_mount
403# define __NR_ia32_mount 21
404# endif
405# ifndef __NR_ia32_read
406# define __NR_ia32_read 3
407# endif
408# ifndef __NR_ia32_write
409# define __NR_ia32_write 4
410# endif
411# ifndef __NR_ia32_open
412# define __NR_ia32_open 5
413# endif
414# ifndef __NR_ia32_close
415# define __NR_ia32_close 6
416# endif
417# ifndef __NR_ia32_unlink
418# define __NR_ia32_unlink 10
419# endif
420#endif
421
422#define osi_procname(procname, size) strncpy(procname, current->comm, size)
423
424#endif /* OSI_MACHDEP_H_ */