Commit | Line | Data |
---|---|---|
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) | |
80 | static 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) | |
86 | static 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) | |
126 | extern int afs_osi_Wakeup(void *event); | |
127 | static inline void | |
128 | wakeup(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) | |
146 | static 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 | ||
170 | typedef struct task_struct afs_proc_t; | |
171 | ||
172 | #ifdef HAVE_LINUX_KUID_T | |
173 | ||
174 | #include <linux/uidgid.h> | |
175 | typedef kuid_t afs_kuid_t; | |
176 | typedef kgid_t afs_kgid_t; | |
177 | extern 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 | ||
185 | static inline kuid_t afs_make_kuid(uid_t uid) { | |
186 | return make_kuid(afs_ns, uid); | |
187 | } | |
188 | static inline kgid_t afs_make_kgid(gid_t gid) { | |
189 | return make_kgid(afs_ns, gid); | |
190 | } | |
191 | static inline uid_t afs_from_kuid(kuid_t kuid) { | |
192 | return from_kuid(afs_ns, kuid); | |
193 | } | |
194 | static inline uid_t afs_from_kgid(kgid_t kgid) { | |
195 | return from_kgid(afs_ns, kgid); | |
196 | } | |
197 | ||
198 | #else | |
199 | ||
200 | typedef uid_t afs_kuid_t; | |
201 | typedef gid_t afs_kgid_t; | |
202 | ||
203 | static inline afs_kuid_t afs_make_kuid(uid_t uid) {return uid;} | |
204 | static inline afs_kgid_t afs_make_kgid(gid_t gid) {return gid;} | |
205 | static inline uid_t afs_from_kuid(afs_kuid_t kuid) {return kuid;} | |
206 | static inline gid_t afs_from_kgid(afs_kgid_t kgid) {return kgid;} | |
207 | static inline unsigned char uid_eq(uid_t a, uid_t b) {return a == b;} | |
208 | static inline unsigned char gid_eq(gid_t a, gid_t b) {return a == b;} | |
209 | static inline unsigned char uid_lt(uid_t a, uid_t b) {return a < b;} | |
210 | static 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 | ||
219 | typedef struct cred afs_ucred_t; | |
220 | typedef 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)) | |
228 | static inline void | |
229 | afs_set_cr_uid(cred_t *cred, uid_t uid) { | |
230 | cred->fsuid = afs_make_kuid(uid); | |
231 | } | |
232 | static inline void | |
233 | afs_set_cr_gid(cred_t *cred, gid_t gid) { | |
234 | cred->fsgid = afs_make_kgid(gid); | |
235 | } | |
236 | static inline void | |
237 | afs_set_cr_ruid(cred_t *cred, uid_t uid) { | |
238 | cred->uid = afs_make_kuid(uid); | |
239 | } | |
240 | static inline void | |
241 | afs_set_cr_rgid(cred_t *cred, gid_t gid) { | |
242 | cred->gid = afs_make_kgid(gid); | |
243 | } | |
244 | static inline void | |
245 | afs_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 | ||
262 | typedef 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 | ||
271 | typedef struct afs_cred afs_ucred_t; | |
272 | # define afs_cr_group_info(cred) ((cred)->cr_group_info) | |
273 | static inline void | |
274 | afs_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 */ | |
300 | typedef enum { AFS_UIOSYS, AFS_UIOUSER } uio_seg_t; | |
301 | typedef enum { UIO_READ, UIO_WRITE } uio_flag_t; | |
302 | struct 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) | |
331 | extern struct mutex afs_global_lock; | |
332 | #else | |
333 | extern struct semaphore afs_global_lock; | |
334 | # define mutex_lock(lock) down(lock) | |
335 | # define mutex_unlock(lock) up(lock) | |
336 | #endif | |
337 | extern int afs_global_owner; | |
338 | ||
339 | #define AFS_GLOCK() \ | |
340 | do { \ | |
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() \ | |
351 | do { \ | |
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_ */ |