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