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