Use an anonymous pointer for lpioctl
[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 int
225 lsetpag(void)
226 {
227
228     AFS_STATCNT(lsetpag);
229     return syscall(AFSCALL_SETPAG, 0, 0, 0, 0, 0);
230 }
231
232 /*
233  * lpioctl -    interface to pioctl()
234  */
235 int
236 lpioctl(char *path, int cmd, void *cmarg, int follow)
237 {
238
239     AFS_STATCNT(lpioctl);
240     return syscall(AFSCALL_PIOCTL, path, cmd, cmarg, follow);
241 }
242
243 #else /* !AFS_AIX32_ENV       */
244
245 #if defined(AFS_SGI_ENV)
246 struct afsargs {
247     sysarg_t syscall;
248     sysarg_t parm1;
249     sysarg_t parm2;
250     sysarg_t parm3;
251     sysarg_t parm4;
252     sysarg_t parm5;
253 };
254
255
256 int
257 Afs_syscall(struct afsargs *uap, rval_t * rvp)
258 {
259     int error;
260     long retval;
261
262     AFS_STATCNT(afs_syscall);
263     switch (uap->syscall) {
264     case AFSCALL_ICL:
265         retval = 0;
266         AFS_GLOCK();
267         error =
268             Afscall_icl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
269                         uap->parm5, &retval);
270         AFS_GUNLOCK();
271         rvp->r_val1 = retval;
272         break;
273 #ifdef AFS_SGI_XFS_IOPS_ENV
274     case AFSCALL_IDEC64:
275         error =
276             afs_syscall_idec64(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
277                                uap->parm5);
278         break;
279     case AFSCALL_IINC64:
280         error =
281             afs_syscall_iinc64(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
282                                uap->parm5);
283         break;
284     case AFSCALL_ILISTINODE64:
285         error =
286             afs_syscall_ilistinode64(uap->parm1, uap->parm2, uap->parm3,
287                                      uap->parm4, uap->parm5);
288         break;
289     case AFSCALL_ICREATENAME64:
290         error =
291             afs_syscall_icreatename64(uap->parm1, uap->parm2, uap->parm3,
292                                       uap->parm4, uap->parm5);
293         break;
294 #endif
295 #ifdef AFS_SGI_VNODE_GLUE
296     case AFSCALL_INIT_KERNEL_CONFIG:
297         error = afs_init_kernel_config(uap->parm1);
298         break;
299 #endif
300     default:
301         error =
302             afs_syscall_call(uap->syscall, uap->parm1, uap->parm2, uap->parm3,
303                              uap->parm4, uap->parm5);
304     }
305     return error;
306 }
307
308 #else /* AFS_SGI_ENV */
309
310 struct iparam {
311     long param1;
312     long param2;
313     long param3;
314     long param4;
315 };
316
317 struct iparam32 {
318     int param1;
319     int param2;
320     int param3;
321     int param4;
322 };
323
324
325 #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))
326 static void
327 iparam32_to_iparam(const struct iparam32 *src, struct iparam *dst)
328 {
329     dst->param1 = src->param1;
330     dst->param2 = src->param2;
331     dst->param3 = src->param3;
332     dst->param4 = src->param4;
333 }
334 #endif
335
336 /*
337  * If you need to change copyin_iparam(), you may also need to change
338  * copyin_afs_ioctl().
339  */
340
341 static int
342 copyin_iparam(caddr_t cmarg, struct iparam *dst)
343 {
344     int code;
345
346 #if defined(AFS_HPUX_64BIT_ENV)
347     struct iparam32 dst32;
348
349     if (is_32bit(u.u_procp)) {  /* is_32bit() in proc_iface.h */
350         AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
351         if (!code)
352             iparam32_to_iparam(&dst32, dst);
353         return code;
354     }
355 #endif /* AFS_HPUX_64BIT_ENV */
356
357 #if defined(AFS_SUN57_64BIT_ENV)
358     struct iparam32 dst32;
359
360     if (get_udatamodel() == DATAMODEL_ILP32) {
361         AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
362         if (!code)
363             iparam32_to_iparam(&dst32, dst);
364         return code;
365     }
366 #endif /* AFS_SUN57_64BIT_ENV */
367
368 #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
369     struct iparam32 dst32;
370
371 #ifdef AFS_SPARC64_LINUX26_ENV
372     if (test_thread_flag(TIF_32BIT))
373 #elif defined(AFS_SPARC64_LINUX24_ENV)
374     if (current->thread.flags & SPARC_FLAG_32BIT)
375 #elif defined(AFS_SPARC64_LINUX20_ENV)
376     if (current->tss.flags & SPARC_FLAG_32BIT)
377
378 #elif defined(AFS_AMD64_LINUX26_ENV)
379     if (test_thread_flag(TIF_IA32))
380 #elif defined(AFS_AMD64_LINUX20_ENV)
381     if (current->thread.flags & THREAD_IA32)
382
383 #elif defined(AFS_PPC64_LINUX26_ENV)
384 #if defined(STRUCT_TASK_STRUCT_HAS_THREAD_INFO)
385     if (current->thread_info->flags & _TIF_32BIT) 
386 #else
387     if (task_thread_info(current)->flags & _TIF_32BIT) 
388 #endif      
389 #elif defined(AFS_PPC64_LINUX20_ENV)
390     if (current->thread.flags & PPC_FLAG_32BIT) 
391
392 #elif defined(AFS_S390X_LINUX26_ENV)
393     if (test_thread_flag(TIF_31BIT))
394 #elif defined(AFS_S390X_LINUX20_ENV)
395     if (current->thread.flags & S390_FLAG_31BIT) 
396
397 #else
398 #error iparam32 not done for this linux platform
399 #endif
400     {
401         AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
402         if (!code)
403             iparam32_to_iparam(&dst32, dst);
404         return code;
405     }
406 #endif /* AFS_LINUX_64BIT_KERNEL */
407
408     AFS_COPYIN(cmarg, (caddr_t) dst, sizeof *dst, code);
409     return code;
410 }
411
412 /* Main entry of all afs system calls */
413 #ifdef  AFS_SUN5_ENV
414 extern int afs_sinited;
415
416 /** The 32 bit OS expects the members of this structure to be 32 bit
417  * quantities and the 64 bit OS expects them as 64 bit quanties. Hence
418  * to accomodate both, *long* is used instead of afs_int32
419  */
420
421 #ifdef AFS_SUN57_ENV
422 struct afssysa {
423     long syscall;
424     long parm1;
425     long parm2;
426     long parm3;
427     long parm4;
428     long parm5;
429     long parm6;
430 };
431 #else
432 struct afssysa {
433     afs_int32 syscall;
434     afs_int32 parm1;
435     afs_int32 parm2;
436     afs_int32 parm3;
437     afs_int32 parm4;
438     afs_int32 parm5;
439     afs_int32 parm6;
440 };
441 #endif
442
443 Afs_syscall(register struct afssysa *uap, rval_t * rvp)
444 {
445     int *retval = &rvp->r_val1;
446 #else /* AFS_SUN5_ENV */
447 #if     defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
448 int
449 afs3_syscall(p, args, retval)
450 #ifdef AFS_FBSD50_ENV
451      struct thread *p;
452 #else
453      struct proc *p;
454 #endif
455      void *args;
456      long *retval;
457 {
458     register struct a {
459         long syscall;
460         long parm1;
461         long parm2;
462         long parm3;
463         long parm4;
464         long parm5;
465         long parm6;
466     } *uap = (struct a *)args;
467 #else /* AFS_OSF_ENV */
468 #ifdef AFS_LINUX20_ENV
469 struct afssysargs {
470     long syscall;
471     long parm1;
472     long parm2;
473     long parm3;
474     long parm4;
475     long parm5;
476     long parm6;                 /* not actually used - should be removed */
477 };
478 /* Linux system calls only set up for 5 arguments. */
479 asmlinkage long
480 afs_syscall(long syscall, long parm1, long parm2, long parm3, long parm4)
481 {
482     struct afssysargs args, *uap = &args;
483     long linux_ret = 0;
484     long *retval = &linux_ret;
485     long eparm[4];              /* matches AFSCALL_ICL in fstrace.c */
486 #ifdef AFS_SPARC64_LINUX24_ENV
487     afs_int32 eparm32[4];
488 #endif
489     /* eparm is also used by AFSCALL_CALL in afsd.c */
490 #else
491 #if defined(UKERNEL)
492 int
493 Afs_syscall()
494 {
495     register struct a {
496         long syscall;
497         long parm1;
498         long parm2;
499         long parm3;
500         long parm4;
501         long parm5;
502         long parm6;
503     } *uap = (struct a *)u.u_ap;
504 #else /* UKERNEL */
505 int
506 Afs_syscall()
507 {
508     register struct a {
509         long syscall;
510         long parm1;
511         long parm2;
512         long parm3;
513         long parm4;
514         long parm5;
515         long parm6;
516     } *uap = (struct a *)u.u_ap;
517 #endif /* UKERNEL */
518 #if defined(AFS_HPUX_ENV)
519     long *retval = &u.u_rval1;
520 #else
521     int *retval = &u.u_rval1;
522 #endif
523 #endif /* AFS_LINUX20_ENV */
524 #endif /* AFS_OSF_ENV */
525 #endif /* AFS_SUN5_ENV */
526     register int code = 0;
527
528     AFS_STATCNT(afs_syscall);
529 #ifdef        AFS_SUN5_ENV
530     rvp->r_vals = 0;
531     if (!afs_sinited) {
532         return (ENODEV);
533     }
534 #endif
535 #ifdef AFS_LINUX20_ENV
536     lock_kernel();
537     /* setup uap for use below - pull out the magic decoder ring to know
538      * which syscalls have folded argument lists.
539      */
540     uap->syscall = syscall;
541     uap->parm1 = parm1;
542     uap->parm2 = parm2;
543     uap->parm3 = parm3;
544     if (syscall == AFSCALL_ICL || syscall == AFSCALL_CALL) {
545 #ifdef AFS_SPARC64_LINUX24_ENV
546 /* from arch/sparc64/kernel/sys_sparc32.c */
547 #define AA(__x)                                \
548 ({     unsigned long __ret;            \
549        __asm__ ("srl   %0, 0, %0"      \
550                 : "=r" (__ret)         \
551                 : "0" (__x));          \
552        __ret;                          \
553 })
554
555
556 #ifdef AFS_SPARC64_LINUX26_ENV
557         if (test_thread_flag(TIF_32BIT))
558 #else
559         if (current->thread.flags & SPARC_FLAG_32BIT)
560 #endif
561         {
562             AFS_COPYIN((char *)parm4, (char *)eparm32, sizeof(eparm32), code);
563             eparm[0] = AA(eparm32[0]);
564             eparm[1] = AA(eparm32[1]);
565             eparm[2] = AA(eparm32[2]);
566 #undef AA
567         } else
568 #endif
569             AFS_COPYIN((char *)parm4, (char *)eparm, sizeof(eparm), code);
570         uap->parm4 = eparm[0];
571         uap->parm5 = eparm[1];
572         uap->parm6 = eparm[2];
573     } else {
574         uap->parm4 = parm4;
575         uap->parm5 = 0;
576         uap->parm6 = 0;
577     }
578 #endif
579 #if defined(AFS_DARWIN80_ENV)
580     get_vfs_context();
581     osi_Assert(*retval == 0);
582 #endif
583 #if defined(AFS_HPUX_ENV)
584     /*
585      * There used to be code here (duplicated from osi_Init()) for
586      * initializing the semaphore used by AFS_GLOCK().  Was the
587      * duplication to handle the case of a dynamically loaded kernel
588      * module?
589      */
590     osi_InitGlock();
591 #endif
592     if (uap->syscall == AFSCALL_CALL) {
593         code =
594             afs_syscall_call(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
595                              uap->parm5, uap->parm6);
596     } else if (uap->syscall == AFSCALL_SETPAG) {
597 #ifdef  AFS_SUN5_ENV
598         register proc_t *procp;
599
600         procp = ttoproc(curthread);
601         AFS_GLOCK();
602         code = afs_setpag(&procp->p_cred);
603         AFS_GUNLOCK();
604 #else
605         AFS_GLOCK();
606 #if     defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
607         code = afs_setpag(p, args, retval);
608 #else /* AFS_OSF_ENV */
609         code = afs_setpag();
610 #endif
611         AFS_GUNLOCK();
612 #endif
613     } else if (uap->syscall == AFSCALL_PIOCTL) {
614         AFS_GLOCK();
615 #if defined(AFS_SUN5_ENV)
616         code =
617             afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
618                                rvp, CRED());
619 #elif defined(AFS_FBSD50_ENV)
620         code =
621             afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
622                                p->td_ucred);
623 #elif defined(AFS_DARWIN80_ENV)
624         code =
625             afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
626                                kauth_cred_get());
627 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
628         code =
629             afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
630                                p->p_cred->pc_ucred);
631 #else
632         code =
633             afs_syscall_pioctl((char *)uap->parm1, (unsigned int)uap->parm2, (caddr_t)uap->parm3,
634                                (int) uap->parm4);
635 #endif
636         AFS_GUNLOCK();
637     } else if (uap->syscall == AFSCALL_ICREATE) {
638         struct iparam iparams;
639
640         code = copyin_iparam((char *)uap->parm3, &iparams);
641         if (code) {
642 #if defined(KERNEL_HAVE_UERROR)
643             setuerror(code);
644 #endif
645         } else
646 #ifdef  AFS_SUN5_ENV
647             code =
648                 afs_syscall_icreate(uap->parm1, uap->parm2, iparams.param1,
649                                     iparams.param2, iparams.param3,
650                                     iparams.param4, rvp, CRED());
651 #else
652             code =
653                 afs_syscall_icreate(uap->parm1, uap->parm2, iparams.param1,
654                                     iparams.param2,
655 #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
656                                     iparams.param3, iparams.param4, retval);
657 #else
658                                     iparams.param3, iparams.param4);
659 #endif
660 #endif /* AFS_SUN5_ENV */
661     } else if (uap->syscall == AFSCALL_IOPEN) {
662 #ifdef  AFS_SUN5_ENV
663         code =
664             afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3, rvp,
665                               CRED());
666 #else
667 #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
668         code = afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3, retval);
669 #else
670         code = afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3);
671 #endif
672 #endif /* AFS_SUN5_ENV */
673     } else if (uap->syscall == AFSCALL_IDEC) {
674 #ifdef  AFS_SUN5_ENV
675         code =
676             afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, -1, rvp,
677                                 CRED());
678 #else
679         code = afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, -1);
680 #endif /* AFS_SUN5_ENV */
681     } else if (uap->syscall == AFSCALL_IINC) {
682 #ifdef  AFS_SUN5_ENV
683         code =
684             afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, 1, rvp,
685                                 CRED());
686 #else
687         code = afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, 1);
688 #endif /* AFS_SUN5_ENV */
689     } else if (uap->syscall == AFSCALL_ICL) {
690         AFS_GLOCK();
691         code =
692             Afscall_icl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
693                         uap->parm5, retval);
694         AFS_GUNLOCK();
695 #ifdef AFS_LINUX20_ENV
696         if (!code) {
697             /* ICL commands can return values. */
698             code = -linux_ret;  /* Gets negated again at exit below */
699         }
700 #else
701         if (code) {
702 #if defined(KERNEL_HAVE_UERROR)
703             setuerror(code);
704 #endif
705         }
706 #endif /* !AFS_LINUX20_ENV */
707     } else {
708 #if defined(KERNEL_HAVE_UERROR)
709         setuerror(EINVAL);
710 #else
711         code = EINVAL;
712 #endif
713     }
714
715 #if defined(AFS_DARWIN80_ENV)
716     if (uap->syscall != AFSCALL_CALL)
717         put_vfs_context();
718 #endif
719 #ifdef AFS_LINUX20_ENV
720     code = -code;
721     unlock_kernel();
722 #endif
723     return code;
724 }
725 #endif /* AFS_SGI_ENV */
726 #endif /* !AFS_AIX32_ENV       */