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