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