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