ce6afdf9a8677b8d0a207b2df832b1bbf22b528d
[openafs.git] / src / afs / afs_syscall.c
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 #include <afsconfig.h>
11 #include "afs/param.h"
12
13 #ifdef IGNORE_SOME_GCC_WARNINGS
14 # pragma GCC diagnostic warning "-Wold-style-definition"
15 # pragma GCC diagnostic warning "-Wstrict-prototypes"
16 #endif
17
18 #include "afs/sysincludes.h"    /* Standard vendor system headers */
19 #include "afsincludes.h"        /* Afs-based standard headers */
20 #include "afs/afs_stats.h"
21 #include "rx/rx_globals.h"
22 #if !defined(UKERNEL) && !defined(AFS_LINUX20_ENV)
23 #include "net/if.h"
24 #ifdef AFS_SGI62_ENV
25 #include "h/hashing.h"
26 #endif
27 #if !defined(AFS_HPUX110_ENV) && !defined(AFS_DARWIN_ENV)
28 #include "netinet/in_var.h"
29 #endif
30 #endif /* !defined(UKERNEL) */
31
32 #if (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)) || defined(AFS_HPUX_64BIT_ENV) || defined(AFS_SUN5_64BIT_ENV) || (defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64)) || defined(NEED_IOCTL32)
33 static void
34 afs_ioctl32_to_afs_ioctl(const struct afs_ioctl32 *src, struct afs_ioctl *dst)
35 {
36 #ifdef AFS_DARWIN100_ENV
37     dst->in = CAST_USER_ADDR_T(src->in);
38     dst->out = CAST_USER_ADDR_T(src->out);
39 #else
40     dst->in = (char *)(unsigned long)src->in;
41     dst->out = (char *)(unsigned long)src->out;
42 #endif
43     dst->in_size = src->in_size;
44     dst->out_size = src->out_size;
45 }
46 #endif
47
48 /*
49  * If you need to change copyin_afs_ioctl(), you may also need to change
50  * copyin_iparam().
51  */
52
53 int
54 #ifdef AFS_DARWIN100_ENV
55 copyin_afs_ioctl(user_addr_t cmarg, struct afs_ioctl *dst)
56 #else
57 copyin_afs_ioctl(caddr_t cmarg, struct afs_ioctl *dst)
58 #endif
59 {
60     int code;
61 #if defined(AFS_DARWIN100_ENV)
62     struct afs_ioctl32 dst32;
63
64     if (!proc_is64bit(current_proc())) {
65         AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
66         if (!code)
67             afs_ioctl32_to_afs_ioctl(&dst32, dst);
68         return code;
69     }
70 #endif
71 #if defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)
72     struct afs_ioctl32 dst32;
73
74     if (!(IS64U)) {
75         AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
76         if (!code)
77             afs_ioctl32_to_afs_ioctl(&dst32, dst);
78         return code;
79     }
80 #endif /* defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL) */
81
82
83 #if defined(AFS_HPUX_64BIT_ENV)
84     struct afs_ioctl32 dst32;
85
86     if (is_32bit(u.u_procp)) {  /* is_32bit() in proc_iface.h */
87         AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
88         if (!code)
89             afs_ioctl32_to_afs_ioctl(&dst32, dst);
90         return code;
91     }
92 #endif /* defined(AFS_HPUX_64BIT_ENV) */
93
94 #if defined(AFS_SUN5_64BIT_ENV)
95     struct afs_ioctl32 dst32;
96
97     if (get_udatamodel() == DATAMODEL_ILP32) {
98         AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
99         if (!code)
100             afs_ioctl32_to_afs_ioctl(&dst32, dst);
101         return code;
102     }
103 #endif /* defined(AFS_SUN5_64BIT_ENV) */
104
105 #if defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64)
106     struct afs_ioctl32 dst32;
107
108     if (!ABI_IS_64BIT(get_current_abi())) {
109         AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
110         if (!code)
111             afs_ioctl32_to_afs_ioctl(&dst32, dst);
112         return code;
113     }
114 #endif /* defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64) */
115
116 #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
117     struct afs_ioctl32 dst32;
118
119 #ifdef AFS_SPARC64_LINUX26_ENV
120     if (test_thread_flag(TIF_32BIT))
121 #elif defined(AFS_SPARC64_LINUX24_ENV)
122     if (current->thread.flags & SPARC_FLAG_32BIT)
123 #elif defined(AFS_SPARC64_LINUX20_ENV)
124     if (current->tss.flags & SPARC_FLAG_32BIT)
125
126 #elif defined(AFS_AMD64_LINUX26_ENV)
127     if (test_thread_flag(TIF_IA32))
128 #elif defined(AFS_AMD64_LINUX20_ENV)
129     if (current->thread.flags & THREAD_IA32)
130
131 #elif defined(AFS_PPC64_LINUX26_ENV)
132 #if defined(STRUCT_TASK_STRUCT_HAS_THREAD_INFO)
133     if (current->thread_info->flags & _TIF_32BIT)
134 #else
135     if (task_thread_info(current)->flags & _TIF_32BIT)
136 #endif
137 #elif defined(AFS_PPC64_LINUX20_ENV)
138     if (current->thread.flags & PPC_FLAG_32BIT)
139
140 #elif defined(AFS_S390X_LINUX26_ENV)
141     if (test_thread_flag(TIF_31BIT))
142 #elif defined(AFS_S390X_LINUX20_ENV)
143     if (current->thread.flags & S390_FLAG_31BIT)
144 #elif defined(AFS_ARM64_LINUX26_ENV)
145     if (is_compat_task())
146
147 #else
148 #error pioctl32 not done for this linux
149 #endif
150     {
151         AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
152         if (!code)
153             afs_ioctl32_to_afs_ioctl(&dst32, dst);
154         return code;
155     }
156 #endif /* defined(AFS_LINUX_64BIT_KERNEL) */
157
158     AFS_COPYIN(cmarg, (caddr_t) dst, sizeof *dst, code);
159     return code;
160 }
161
162
163 #ifdef AFS_AIX32_ENV
164
165 #include "sys/lockl.h"
166
167 /*
168  * syscall -    this is the VRMIX system call entry point.
169  *
170  * NOTE:
171  *      THIS SHOULD BE CHANGED TO afs_syscall(), but requires
172  *      all the user-level calls to `syscall' to change.
173  */
174 syscall(syscall, p1, p2, p3, p4, p5, p6)
175 {
176     int rval1 = 0, code;
177     int monster;
178     int retval = 0;
179 #ifndef AFS_AIX41_ENV
180     extern lock_t kernel_lock;
181     monster = lockl(&kernel_lock, LOCK_SHORT);
182 #endif /* !AFS_AIX41_ENV */
183
184     AFS_STATCNT(syscall);
185     setuerror(0);
186     switch (syscall) {
187     case AFSCALL_CALL:
188         rval1 = afs_syscall_call(p1, p2, p3, p4, p5, p6);
189         break;
190
191     case AFSCALL_SETPAG:
192         AFS_GLOCK();
193         rval1 = afs_setpag();
194         AFS_GUNLOCK();
195         break;
196
197     case AFSCALL_PIOCTL:
198         AFS_GLOCK();
199         rval1 = afs_syscall_pioctl(p1, p2, p3, p4);
200         AFS_GUNLOCK();
201         break;
202
203     case AFSCALL_ICREATE:
204         rval1 = afs_syscall_icreate(p1, p2, p3, p4, p5, p6);
205         break;
206
207     case AFSCALL_IOPEN:
208         rval1 = afs_syscall_iopen(p1, p2, p3);
209         break;
210
211     case AFSCALL_IDEC:
212         rval1 = afs_syscall_iincdec(p1, p2, p3, -1);
213         break;
214
215     case AFSCALL_IINC:
216         rval1 = afs_syscall_iincdec(p1, p2, p3, 1);
217         break;
218
219     case AFSCALL_ICL:
220         AFS_GLOCK();
221         code = Afscall_icl(p1, p2, p3, p4, p5, &retval);
222         AFS_GUNLOCK();
223         if (!code)
224             rval1 = retval;
225         if (!rval1)
226             rval1 = code;
227         break;
228
229     default:
230         rval1 = EINVAL;
231         setuerror(EINVAL);
232         break;
233     }
234
235   out:
236 #ifndef AFS_AIX41_ENV
237     if (monster != LOCK_NEST)
238         unlockl(&kernel_lock);
239 #endif /* !AFS_AIX41_ENV */
240     return getuerror()? -1 : rval1;
241 }
242
243 /*
244  * lsetpag -    interface to afs_setpag().
245  */
246 int
247 lsetpag(void)
248 {
249
250     AFS_STATCNT(lsetpag);
251     return syscall(AFSCALL_SETPAG, 0, 0, 0, 0, 0);
252 }
253
254 /*
255  * lpioctl -    interface to pioctl()
256  */
257 int
258 lpioctl(char *path, int cmd, void *cmarg, int follow)
259 {
260
261     AFS_STATCNT(lpioctl);
262     return syscall(AFSCALL_PIOCTL, path, cmd, cmarg, follow);
263 }
264
265 #else /* !AFS_AIX32_ENV       */
266
267 #if defined(AFS_SGI_ENV)
268 struct afsargs {
269     sysarg_t syscall;
270     sysarg_t parm1;
271     sysarg_t parm2;
272     sysarg_t parm3;
273     sysarg_t parm4;
274     sysarg_t parm5;
275 };
276
277
278 int
279 Afs_syscall(struct afsargs *uap, rval_t * rvp)
280 {
281     int error;
282     long retval;
283
284     AFS_STATCNT(afs_syscall);
285     switch (uap->syscall) {
286     case AFSCALL_ICL:
287         retval = 0;
288         AFS_GLOCK();
289         error =
290             Afscall_icl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
291                         uap->parm5, &retval);
292         AFS_GUNLOCK();
293         rvp->r_val1 = retval;
294         break;
295 #ifdef AFS_SGI_XFS_IOPS_ENV
296     case AFSCALL_IDEC64:
297         error =
298             afs_syscall_idec64(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
299                                uap->parm5);
300         break;
301     case AFSCALL_IINC64:
302         error =
303             afs_syscall_iinc64(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
304                                uap->parm5);
305         break;
306     case AFSCALL_ILISTINODE64:
307         error =
308             afs_syscall_ilistinode64(uap->parm1, uap->parm2, uap->parm3,
309                                      uap->parm4, uap->parm5);
310         break;
311     case AFSCALL_ICREATENAME64:
312         error =
313             afs_syscall_icreatename64(uap->parm1, uap->parm2, uap->parm3,
314                                       uap->parm4, uap->parm5);
315         break;
316 #endif
317 #ifdef AFS_SGI_VNODE_GLUE
318     case AFSCALL_INIT_KERNEL_CONFIG:
319         error = afs_init_kernel_config(uap->parm1);
320         break;
321 #endif
322     default:
323         error =
324             afs_syscall_call(uap->syscall, uap->parm1, uap->parm2, uap->parm3,
325                              uap->parm4, uap->parm5);
326     }
327     return error;
328 }
329
330 #else /* AFS_SGI_ENV */
331
332 struct iparam {
333     iparmtype param1;
334     iparmtype param2;
335     iparmtype param3;
336     iparmtype param4;
337 };
338
339 struct iparam32 {
340     int param1;
341     int param2;
342     int param3;
343     int param4;
344 };
345
346
347 #if defined(AFS_HPUX_64BIT_ENV) || defined(AFS_SUN5_64BIT_ENV) || (defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)) || defined(NEED_IOCTL32)
348 static void
349 iparam32_to_iparam(const struct iparam32 *src, struct iparam *dst)
350 {
351     dst->param1 = (iparmtype)(uintptrsz)src->param1;
352     dst->param2 = (iparmtype)(uintptrsz)src->param2;
353     dst->param3 = (iparmtype)(uintptrsz)src->param3;
354     dst->param4 = (iparmtype)(uintptrsz)src->param4;
355 }
356 #endif
357
358 /*
359  * If you need to change copyin_iparam(), you may also need to change
360  * copyin_afs_ioctl().
361  *
362  * This function is needed only for icreate, meaning, only on platforms
363  * providing the inode fileserver.
364  */
365
366 static int
367 copyin_iparam(caddr_t cmarg, struct iparam *dst)
368 {
369     int code;
370
371 #if defined(AFS_HPUX_64BIT_ENV)
372     struct iparam32 dst32;
373
374     if (is_32bit(u.u_procp)) {  /* is_32bit() in proc_iface.h */
375         AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
376         if (!code)
377             iparam32_to_iparam(&dst32, dst);
378         return code;
379     }
380 #endif /* AFS_HPUX_64BIT_ENV */
381
382 #if defined(AFS_SUN5_64BIT_ENV)
383     struct iparam32 dst32;
384
385     if (get_udatamodel() == DATAMODEL_ILP32) {
386         AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
387         if (!code)
388             iparam32_to_iparam(&dst32, dst);
389         return code;
390     }
391 #endif /* AFS_SUN5_64BIT_ENV */
392
393 #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
394     struct iparam32 dst32;
395
396 #ifdef AFS_SPARC64_LINUX26_ENV
397     if (test_thread_flag(TIF_32BIT))
398 #elif defined(AFS_SPARC64_LINUX24_ENV)
399     if (current->thread.flags & SPARC_FLAG_32BIT)
400 #elif defined(AFS_SPARC64_LINUX20_ENV)
401     if (current->tss.flags & SPARC_FLAG_32BIT)
402
403 #elif defined(AFS_AMD64_LINUX26_ENV)
404     if (test_thread_flag(TIF_IA32))
405 #elif defined(AFS_AMD64_LINUX20_ENV)
406     if (current->thread.flags & THREAD_IA32)
407
408 #elif defined(AFS_PPC64_LINUX26_ENV)
409 #if defined(STRUCT_TASK_STRUCT_HAS_THREAD_INFO)
410     if (current->thread_info->flags & _TIF_32BIT)
411 #else
412     if (task_thread_info(current)->flags & _TIF_32BIT)
413 #endif
414 #elif defined(AFS_PPC64_LINUX20_ENV)
415     if (current->thread.flags & PPC_FLAG_32BIT)
416
417 #elif defined(AFS_S390X_LINUX26_ENV)
418     if (test_thread_flag(TIF_31BIT))
419 #elif defined(AFS_S390X_LINUX20_ENV)
420     if (current->thread.flags & S390_FLAG_31BIT)
421 #elif defined(AFS_ARM64_LINUX26_ENV)
422     if (is_compat_task())
423
424 #else
425 #error iparam32 not done for this linux platform
426 #endif
427     {
428         AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
429         if (!code)
430             iparam32_to_iparam(&dst32, dst);
431         return code;
432     }
433 #endif /* AFS_LINUX_64BIT_KERNEL */
434
435     AFS_COPYIN(cmarg, (caddr_t) dst, sizeof *dst, code);
436     return code;
437 }
438
439 /* Main entry of all afs system calls */
440 #ifdef  AFS_SUN5_ENV
441 extern int afs_sinited;
442
443 Afs_syscall(struct afssysa *uap, rval_t * rvp)
444 {
445     int *retval = &rvp->r_val1;
446 #elif defined(AFS_DARWIN100_ENV)
447 struct afssysa {
448     afs_int32 syscall;
449     afs_int32 parm1;
450     afs_int32 parm2;
451     afs_int32 parm3;
452     afs_int32 parm4;
453     afs_int32 parm5;
454     afs_int32 parm6;
455 };
456 struct afssysa64 {
457     afs_int64 parm1;
458     afs_int64 parm2;
459     afs_int64 parm3;
460     afs_int64 parm4;
461     afs_int64 parm5;
462     afs_int64 parm6;
463     afs_int32 syscall;
464 };
465 int
466 afs3_syscall(afs_proc_t *p, void *args, unsigned int *retval)
467 {
468     struct afssysa64 *uap64 = NULL;
469     struct afssysa *uap = NULL;
470 #elif defined(AFS_FBSD_ENV)
471 int
472 afs3_syscall(struct thread *p, void *args)
473 {
474     struct a {
475         long syscall;
476         long parm1;
477         long parm2;
478         long parm3;
479         long parm4;
480         long parm5;
481         long parm6;
482     } *uap = (struct a *)args;
483     long fbsd_ret = 0;
484     long *retval = &fbsd_ret;
485 #elif defined(AFS_NBSD40_ENV)
486 int
487 afs3_syscall(struct lwp *p, const void *args, register_t *retval)
488 {
489     /* see osi_machdep.h */
490     struct afs_sysargs *uap = (struct afs_sysargs *) args;
491 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
492 int
493 afs3_syscall(afs_proc_t *p, void *args, long *retval)
494 {
495     struct a {
496         long syscall;
497         long parm1;
498         long parm2;
499         long parm3;
500         long parm4;
501         long parm5;
502         long parm6;
503     } *uap = (struct a *)args;
504 #elif defined(AFS_LINUX20_ENV)
505 struct afssysargs {
506     long syscall;
507     long parm1;
508     long parm2;
509     long parm3;
510     long parm4;
511     long parm5;
512     long parm6;                 /* not actually used - should be removed */
513 };
514 /* Linux system calls only set up for 5 arguments. */
515 asmlinkage long
516 afs_syscall(long syscall, long parm1, long parm2, long parm3, long parm4)
517 {
518     struct afssysargs args, *uap = &args;
519     long linux_ret = 0;
520     long *retval = &linux_ret;
521     long eparm[4];              /* matches AFSCALL_ICL in fstrace.c */
522 # ifdef AFS_SPARC64_LINUX24_ENV
523     afs_int32 eparm32[4];
524 # endif
525     /* eparm is also used by AFSCALL_CALL in afsd.c */
526 #else
527 # if defined(UKERNEL)
528 int
529 Afs_syscall(void)
530 {
531     struct a {
532         long syscall;
533         long parm1;
534         long parm2;
535         long parm3;
536         long parm4;
537         long parm5;
538         long parm6;
539     } *uap = (struct a *)get_user_struct()->u_ap;
540 # else /* UKERNEL */
541 int
542 Afs_syscall()
543 {
544     struct a {
545         long syscall;
546         long parm1;
547         long parm2;
548         long parm3;
549         long parm4;
550         long parm5;
551         long parm6;
552     } *uap = (struct a *)u.u_ap;
553 # endif /* UKERNEL */
554 # if defined(AFS_HPUX_ENV)
555     long *retval = &u.u_rval1;
556 # elif defined(UKERNEL)
557     int *retval = &(get_user_struct()->u_rval1);
558 # else
559     int *retval = &u.u_rval1;
560 # endif
561 #endif
562     int code = 0;
563
564     AFS_STATCNT(afs_syscall);
565 #ifdef        AFS_SUN5_ENV
566     rvp->r_vals = 0;
567     if (!afs_sinited) {
568         return (ENODEV);
569     }
570 #endif
571 #ifdef AFS_LINUX20_ENV
572     /* setup uap for use below - pull out the magic decoder ring to know
573      * which syscalls have folded argument lists.
574      */
575     uap->syscall = syscall;
576     uap->parm1 = parm1;
577     uap->parm2 = parm2;
578     uap->parm3 = parm3;
579     if (syscall == AFSCALL_ICL || syscall == AFSCALL_CALL) {
580 #ifdef AFS_SPARC64_LINUX24_ENV
581 /* from arch/sparc64/kernel/sys_sparc32.c */
582 #define AA(__x)                                \
583 ({     unsigned long __ret;            \
584        __asm__ ("srl   %0, 0, %0"      \
585                 : "=r" (__ret)         \
586                 : "0" (__x));          \
587        __ret;                          \
588 })
589
590
591 #ifdef AFS_SPARC64_LINUX26_ENV
592         if (test_thread_flag(TIF_32BIT))
593 #else
594         if (current->thread.flags & SPARC_FLAG_32BIT)
595 #endif
596         {
597             AFS_COPYIN((char *)parm4, (char *)eparm32, sizeof(eparm32), code);
598             eparm[0] = AA(eparm32[0]);
599             eparm[1] = AA(eparm32[1]);
600             eparm[2] = AA(eparm32[2]);
601 #undef AA
602         } else
603 #endif
604             AFS_COPYIN((char *)parm4, (char *)eparm, sizeof(eparm), code);
605         uap->parm4 = eparm[0];
606         uap->parm5 = eparm[1];
607         uap->parm6 = eparm[2];
608     } else {
609         uap->parm4 = parm4;
610         uap->parm5 = 0;
611         uap->parm6 = 0;
612     }
613 #endif
614 #if defined(AFS_DARWIN80_ENV)
615     get_vfs_context();
616     osi_Assert(*retval == 0);
617 #ifdef AFS_DARWIN100_ENV
618     if (proc_is64bit(p)) {
619         uap64 = (struct afssysa64 *)args;
620         if (uap64->syscall == AFSCALL_CALL) {
621             code =
622                 afs_syscall64_call(uap64->parm1, uap64->parm2, uap64->parm3,
623                                    uap64->parm4, uap64->parm5, uap64->parm6);
624             /* pass back the code as syscall retval */
625             if (code < 0) {
626                 *retval = code;
627                 code = 0;
628             }
629         } else if (uap64->syscall == AFSCALL_SETPAG) {
630             AFS_GLOCK();
631             code = afs_setpag(p, args, retval);
632             AFS_GUNLOCK();
633         } else if (uap64->syscall == AFSCALL_PIOCTL) {
634             AFS_GLOCK();
635             code =
636                 afs_syscall64_pioctl(uap64->parm1, (unsigned int)uap64->parm2,
637                                      uap64->parm3, (int)uap64->parm4,
638                                      kauth_cred_get());
639             AFS_GUNLOCK();
640         } else if (uap64->syscall == AFSCALL_ICL) {
641             AFS_GLOCK();
642             code =
643                 Afscall64_icl(uap64->parm1, uap64->parm2, uap64->parm3,
644                             uap64->parm4, uap64->parm5, retval);
645             AFS_GUNLOCK();
646         } else
647             code = EINVAL;
648         if (uap64->syscall != AFSCALL_CALL)
649             put_vfs_context();
650     } else { /* and the default case for 32 bit procs */
651 #endif
652         uap = (struct afssysa *)args;
653 #endif
654 #if defined(AFS_HPUX_ENV)
655     /*
656      * There used to be code here (duplicated from osi_Init()) for
657      * initializing the semaphore used by AFS_GLOCK().  Was the
658      * duplication to handle the case of a dynamically loaded kernel
659      * module?
660      */
661         osi_InitGlock();
662 #endif
663
664 #if defined(AFS_NBSD40_ENV)
665         if (SCARG(uap, syscall) == AFSCALL_CALL) {
666             code =
667                 afs_syscall_call(SCARG(uap, parm1), SCARG(uap, parm2),
668                                  SCARG(uap, parm3), SCARG(uap, parm4),
669                                  SCARG(uap, parm5), SCARG(uap, parm6));
670         } else if (SCARG(uap, syscall) == AFSCALL_SETPAG) {
671 #else
672         if (uap->syscall == AFSCALL_CALL) {
673             code =
674                 afs_syscall_call(uap->parm1, uap->parm2, uap->parm3,
675                                  uap->parm4, uap->parm5, uap->parm6);
676 #ifdef AFS_DARWIN_ENV
677             /* pass back the code as syscall retval */
678             if (code < 0) {
679                 *retval = code;
680                 code = 0;
681             }
682 #endif
683         } else if (uap->syscall == AFSCALL_SETPAG) {
684 #endif
685 #ifdef  AFS_SUN5_ENV
686             proc_t *procp;
687
688             procp = ttoproc(curthread);
689             AFS_GLOCK();
690             code = afs_setpag(&procp->p_cred);
691             AFS_GUNLOCK();
692 #else
693             AFS_GLOCK();
694 #if     defined(AFS_FBSD_ENV)
695             code = afs_setpag(p, args);
696 #elif   defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
697             code = afs_setpag(p, args, retval);
698 #else /* AFS_DARWIN_ENV || AFS_XBSD_ENV */
699             code = afs_setpag();
700 #endif
701             AFS_GUNLOCK();
702 #endif
703         } else if
704 #if defined(AFS_NBSD40_ENV)
705                 (SCARG(uap, syscall) == AFSCALL_PIOCTL) {
706 #else
707             (uap->syscall == AFSCALL_PIOCTL) {
708 #endif
709             AFS_GLOCK();
710 #if defined(AFS_SUN5_ENV)
711             code =
712                 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3,
713                                    uap->parm4, rvp, CRED());
714 #elif defined(AFS_FBSD_ENV)
715             code =
716                 afs_syscall_pioctl((void *)uap->parm1, uap->parm2, (void *)uap->parm3,
717                                    uap->parm4, p->td_ucred);
718 #elif defined(AFS_DARWIN80_ENV)
719             code =
720                 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3,
721                                    uap->parm4, kauth_cred_get());
722 #elif defined(AFS_NBSD40_ENV)
723             code =
724                 afs_syscall_pioctl((char *)SCARG(uap, parm1), SCARG(uap, parm2),
725                                    (void *)SCARG(uap, parm3), SCARG(uap, parm4),
726                                    kauth_cred_get());
727 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
728             code =
729                 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3,
730                                    uap->parm4, p->p_cred->pc_ucred);
731 #else
732             code =
733                 afs_syscall_pioctl((char *)uap->parm1,
734                                    (unsigned int)uap->parm2,
735                                    (caddr_t)uap->parm3,
736                                    (int) uap->parm4);
737 #endif
738             AFS_GUNLOCK();
739
740 #ifdef AFS_NBSD40_ENV
741             } else if (SCARG(uap, syscall) == AFSCALL_ICREATE) {
742                 struct iparam iparams;
743                 code = copyin_iparam((char *) SCARG(uap, parm3), &iparams);
744 #else
745         } else if (uap->syscall == AFSCALL_ICREATE) {
746             struct iparam iparams;
747
748             code = copyin_iparam((char *)uap->parm3, &iparams);
749 #endif
750             if (code) {
751 #if defined(KERNEL_HAVE_UERROR)
752                 setuerror(code);
753 #endif
754             } else {
755 #if defined(AFS_SUN5_ENV)
756                 code =
757                     afs_syscall_icreate(uap->parm1, uap->parm2, iparams.param1,
758                                         iparams.param2, iparams.param3,
759                                         iparams.param4, rvp, CRED());
760 #elif defined(AFS_NBSD40_ENV)
761                 code =
762                         afs_syscall_icreate(SCARG(uap, parm1), SCARG(uap, parm2),
763                                 iparams.param1, iparams.param2, iparams.param3,
764                                 iparams.param4, retval
765                         );
766 #else
767                 code =
768                     afs_syscall_icreate(uap->parm1, uap->parm2, iparams.param1,
769                                         iparams.param2, iparams.param3,
770                                         iparams.param4
771 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
772                                         , retval
773 #endif
774                         );
775 #endif /* AFS_SUN5_ENV */
776             }
777 #if defined(AFS_NBSD40_ENV)
778             } else if (SCARG(uap, syscall) == AFSCALL_IOPEN) {
779 #else
780             } else if (uap->syscall == AFSCALL_IOPEN) {
781 #endif /* !AFS_NBSD40_ENV */
782 #if defined(AFS_SUN5_ENV)
783             code =
784                 afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3, rvp,
785                                   CRED());
786 #elif defined(AFS_NBSD40_ENV)
787             code = afs_syscall_iopen(SCARG(uap, parm1), SCARG(uap, parm2),
788                                      SCARG(uap, parm3), retval);
789 #else
790             code = afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3
791 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
792                                      , retval
793 #endif
794                 );
795 #endif /* AFS_SUN5_ENV */
796 #if defined(AFS_NBSD40_ENV)
797         } else if (SCARG(uap, syscall) == AFSCALL_IDEC) {
798 #else
799         } else if (uap->syscall == AFSCALL_IDEC) {
800 #endif
801 #if defined(AFS_NBSD40_ENV)
802             code = afs_syscall_iincdec(SCARG(uap, parm1), SCARG(uap, parm2),
803                                          SCARG(uap, parm3), -1);
804 #else
805
806
807             code =
808                 afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, -1
809 #if defined(AFS_SUN5_ENV)
810                                     , rvp, CRED()
811 #endif
812                     );
813
814 #endif /* !AFS_NBSD40_ENV */
815 #if defined(AFS_NBSD40_ENV)
816             } else if (SCARG(uap, syscall) == AFSCALL_IINC) {
817 #else
818             } else if (uap->syscall == AFSCALL_IINC) {
819 #endif
820 #if defined(AFS_NBSD40_ENV)
821               code = afs_syscall_iincdec(SCARG(uap, parm1), SCARG(uap, parm2),
822                                          SCARG(uap, parm3), 1);
823 #else
824             code =
825                 afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, 1
826 #ifdef  AFS_SUN5_ENV
827                                     , rvp, CRED()
828 #endif
829                     );
830 #endif /* !AFS_NBSD40_ENV */
831 #if defined(AFS_NBSD40_ENV)
832             } else if (SCARG(uap, syscall) == AFSCALL_ICL) {
833 #else
834             } else if (uap->syscall == AFSCALL_ICL) {
835 #endif
836             AFS_GLOCK();
837             code =
838 #if defined(AFS_NBSD40_ENV)
839               Afscall_icl(SCARG(uap, parm1), SCARG(uap, parm2),
840                           SCARG(uap, parm3), SCARG(uap, parm4),
841                           SCARG(uap, parm5), retval);
842 #else
843                 Afscall_icl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
844                             uap->parm5, (long *)retval);
845 #endif /* !AFS_NBSD40_ENV */
846             AFS_GUNLOCK();
847 #ifdef AFS_LINUX20_ENV
848             if (!code) {
849                 /* ICL commands can return values. */
850                 code = -linux_ret;      /* Gets negated again at exit below */
851             }
852 #else
853             if (code) {
854 #if defined(KERNEL_HAVE_UERROR)
855                 setuerror(code);
856 #endif
857             }
858 #endif /* !AFS_LINUX20_ENV */
859         } else {
860 #if defined(KERNEL_HAVE_UERROR)
861             setuerror(EINVAL);
862 #else
863             code = EINVAL;
864 #endif
865         }
866 #if defined(AFS_DARWIN80_ENV)
867         if (uap->syscall != AFSCALL_CALL)
868             put_vfs_context();
869 #ifdef AFS_DARWIN100_ENV
870     } /* 32 bit procs */
871 #endif
872 #endif
873 #ifdef AFS_LINUX20_ENV
874     code = -code;
875 #endif
876     return code;
877 }
878 #endif /* AFS_SGI_ENV */
879 #endif /* !AFS_AIX32_ENV */