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