2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include "afs/param.h"
13 #ifdef IGNORE_SOME_GCC_WARNINGS
14 # pragma GCC diagnostic warning "-Wold-style-definition"
15 # pragma GCC diagnostic warning "-Wstrict-prototypes"
18 #include "afs/sysincludes.h" /* Standard vendor system headers */
19 #include "afsincludes.h" /* Afs-based standard headers */
20 #include "afs/afs_stats.h"
21 #include "rx/rx_globals.h"
22 #if !defined(UKERNEL) && !defined(AFS_LINUX_ENV)
25 #include "h/hashing.h"
27 #if !defined(AFS_HPUX110_ENV) && !defined(AFS_DARWIN_ENV)
28 #include "netinet/in_var.h"
30 #endif /* !defined(UKERNEL) */
32 #if (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)) || defined(AFS_HPUX_64BIT_ENV) || defined(AFS_SUN5_64BIT_ENV) || (defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64)) || defined(NEED_IOCTL32)
34 afs_ioctl32_to_afs_ioctl(const struct afs_ioctl32 *src, struct afs_ioctl *dst)
36 #ifdef AFS_DARWIN100_ENV
37 dst->in = CAST_USER_ADDR_T(src->in);
38 dst->out = CAST_USER_ADDR_T(src->out);
40 dst->in = (char *)(unsigned long)src->in;
41 dst->out = (char *)(unsigned long)src->out;
43 dst->in_size = src->in_size;
44 dst->out_size = src->out_size;
49 * If you need to change copyin_afs_ioctl(), you may also need to change
54 #ifdef AFS_DARWIN100_ENV
55 copyin_afs_ioctl(user_addr_t cmarg, struct afs_ioctl *dst)
57 copyin_afs_ioctl(caddr_t cmarg, struct afs_ioctl *dst)
61 #if defined(AFS_DARWIN100_ENV)
62 struct afs_ioctl32 dst32;
64 if (!proc_is64bit(current_proc())) {
65 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
67 afs_ioctl32_to_afs_ioctl(&dst32, dst);
71 #if defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)
72 struct afs_ioctl32 dst32;
75 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
77 afs_ioctl32_to_afs_ioctl(&dst32, dst);
80 #endif /* defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL) */
83 #if defined(AFS_HPUX_64BIT_ENV)
84 struct afs_ioctl32 dst32;
86 if (is_32bit(u.u_procp)) { /* is_32bit() in proc_iface.h */
87 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
89 afs_ioctl32_to_afs_ioctl(&dst32, dst);
92 #endif /* defined(AFS_HPUX_64BIT_ENV) */
94 #if defined(AFS_SUN5_64BIT_ENV)
95 struct afs_ioctl32 dst32;
97 if (get_udatamodel() == DATAMODEL_ILP32) {
98 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
100 afs_ioctl32_to_afs_ioctl(&dst32, dst);
103 #endif /* defined(AFS_SUN5_64BIT_ENV) */
105 #if defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64)
106 struct afs_ioctl32 dst32;
108 if (!ABI_IS_64BIT(get_current_abi())) {
109 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
111 afs_ioctl32_to_afs_ioctl(&dst32, dst);
114 #endif /* defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64) */
116 #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX_ENV) && !defined(AFS_IA64_LINUX_ENV)
117 if (afs_in_compat_syscall()) {
118 struct afs_ioctl32 dst32;
120 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
122 afs_ioctl32_to_afs_ioctl(&dst32, dst);
125 #endif /* defined(AFS_LINUX_64BIT_KERNEL) */
127 AFS_COPYIN(cmarg, (caddr_t) dst, sizeof *dst, code);
134 #include "sys/lockl.h"
137 * syscall - this is the VRMIX system call entry point.
140 * THIS SHOULD BE CHANGED TO afs_syscall(), but requires
141 * all the user-level calls to `syscall' to change.
143 syscall(syscall, p1, p2, p3, p4, p5, p6)
148 #ifndef AFS_AIX41_ENV
149 extern lock_t kernel_lock;
150 monster = lockl(&kernel_lock, LOCK_SHORT);
151 #endif /* !AFS_AIX41_ENV */
153 AFS_STATCNT(syscall);
157 rval1 = afs_syscall_call(p1, p2, p3, p4, p5, p6);
162 rval1 = afs_setpag();
168 rval1 = afs_syscall_pioctl(p1, p2, p3, p4);
172 case AFSCALL_ICREATE:
173 rval1 = afs_syscall_icreate(p1, p2, p3, p4, p5, p6);
177 rval1 = afs_syscall_iopen(p1, p2, p3);
181 rval1 = afs_syscall_iincdec(p1, p2, p3, -1);
185 rval1 = afs_syscall_iincdec(p1, p2, p3, 1);
190 code = Afscall_icl(p1, p2, p3, p4, p5, &retval);
205 #ifndef AFS_AIX41_ENV
206 if (monster != LOCK_NEST)
207 unlockl(&kernel_lock);
208 #endif /* !AFS_AIX41_ENV */
209 return getuerror()? -1 : rval1;
213 * lsetpag - interface to afs_setpag().
219 AFS_STATCNT(lsetpag);
220 return syscall(AFSCALL_SETPAG, 0, 0, 0, 0, 0);
224 * lpioctl - interface to pioctl()
227 lpioctl(char *path, int cmd, void *cmarg, int follow)
230 AFS_STATCNT(lpioctl);
231 return syscall(AFSCALL_PIOCTL, path, cmd, cmarg, follow);
234 #else /* !AFS_AIX32_ENV */
236 #if defined(AFS_SGI_ENV)
248 Afs_syscall(struct afsargs *uap, rval_t * rvp)
253 AFS_STATCNT(afs_syscall);
254 switch (uap->syscall) {
259 Afscall_icl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
260 uap->parm5, &retval);
262 rvp->r_val1 = retval;
264 #ifdef AFS_SGI_XFS_IOPS_ENV
267 afs_syscall_idec64(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
272 afs_syscall_iinc64(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
275 case AFSCALL_ILISTINODE64:
277 afs_syscall_ilistinode64(uap->parm1, uap->parm2, uap->parm3,
278 uap->parm4, uap->parm5);
280 case AFSCALL_ICREATENAME64:
282 afs_syscall_icreatename64(uap->parm1, uap->parm2, uap->parm3,
283 uap->parm4, uap->parm5);
286 #ifdef AFS_SGI_VNODE_GLUE
287 case AFSCALL_INIT_KERNEL_CONFIG:
288 error = afs_init_kernel_config(uap->parm1);
293 afs_syscall_call(uap->syscall, uap->parm1, uap->parm2, uap->parm3,
294 uap->parm4, uap->parm5);
299 #else /* AFS_SGI_ENV */
316 #if defined(AFS_HPUX_64BIT_ENV) || defined(AFS_SUN5_64BIT_ENV) || (defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX_ENV) && !defined(AFS_IA64_LINUX_ENV)) || defined(NEED_IOCTL32)
318 iparam32_to_iparam(const struct iparam32 *src, struct iparam *dst)
320 dst->param1 = (iparmtype)(uintptrsz)src->param1;
321 dst->param2 = (iparmtype)(uintptrsz)src->param2;
322 dst->param3 = (iparmtype)(uintptrsz)src->param3;
323 dst->param4 = (iparmtype)(uintptrsz)src->param4;
328 * If you need to change copyin_iparam(), you may also need to change
329 * copyin_afs_ioctl().
331 * This function is needed only for icreate, meaning, only on platforms
332 * providing the inode fileserver.
336 copyin_iparam(caddr_t cmarg, struct iparam *dst)
340 #if defined(AFS_HPUX_64BIT_ENV)
341 struct iparam32 dst32;
343 if (is_32bit(u.u_procp)) { /* is_32bit() in proc_iface.h */
344 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
346 iparam32_to_iparam(&dst32, dst);
349 #endif /* AFS_HPUX_64BIT_ENV */
351 #if defined(AFS_SUN5_64BIT_ENV)
352 struct iparam32 dst32;
354 if (get_udatamodel() == DATAMODEL_ILP32) {
355 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
357 iparam32_to_iparam(&dst32, dst);
360 #endif /* AFS_SUN5_64BIT_ENV */
362 #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX_ENV) && !defined(AFS_IA64_LINUX_ENV)
363 if (afs_in_compat_syscall()) {
364 struct iparam32 dst32;
366 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
368 iparam32_to_iparam(&dst32, dst);
371 #endif /* AFS_LINUX_64BIT_KERNEL */
373 AFS_COPYIN(cmarg, (caddr_t) dst, sizeof *dst, code);
377 /* Main entry of all afs system calls */
379 extern int afs_sinited;
381 Afs_syscall(struct afssysa *uap, rval_t * rvp)
383 int *retval = &rvp->r_val1;
384 #elif defined(AFS_DARWIN100_ENV)
404 afs3_syscall(afs_proc_t *p, void *args, unsigned int *retval)
406 struct afssysa64 *uap64 = NULL;
407 struct afssysa *uap = NULL;
408 #elif defined(AFS_FBSD_ENV)
410 afs3_syscall(struct thread *p, void *args)
420 } *uap = (struct a *)args;
422 long *retval = &fbsd_ret;
423 #elif defined(AFS_NBSD40_ENV)
425 afs3_syscall(struct lwp *p, const void *args, register_t *retval)
427 /* see osi_machdep.h */
428 struct afs_sysargs *uap = (struct afs_sysargs *) args;
429 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
431 afs3_syscall(afs_proc_t *p, void *args, long *retval)
441 } *uap = (struct a *)args;
442 #elif defined(AFS_LINUX_ENV)
450 long parm6; /* not actually used - should be removed */
452 /* Linux system calls only set up for 5 arguments. */
454 afs_syscall(long syscall, long parm1, long parm2, long parm3, long parm4)
456 struct afssysargs args, *uap = &args;
458 long *retval = &linux_ret;
459 long eparm[4]; /* matches AFSCALL_ICL in fstrace.c */
460 # ifdef AFS_SPARC64_LINUX_ENV
461 afs_int32 eparm32[4];
463 /* eparm is also used by AFSCALL_CALL in afsd.c */
465 # if defined(UKERNEL)
477 } *uap = (struct a *)get_user_struct()->u_ap;
490 } *uap = (struct a *)u.u_ap;
491 # endif /* UKERNEL */
492 # if defined(AFS_HPUX_ENV)
493 long *retval = &u.u_rval1;
494 # elif defined(UKERNEL)
495 int *retval = &(get_user_struct()->u_rval1);
497 int *retval = &u.u_rval1;
502 AFS_STATCNT(afs_syscall);
510 /* setup uap for use below - pull out the magic decoder ring to know
511 * which syscalls have folded argument lists.
513 uap->syscall = syscall;
517 if (syscall == AFSCALL_ICL || syscall == AFSCALL_CALL) {
518 #ifdef AFS_SPARC64_LINUX_ENV
519 /* from arch/sparc64/kernel/sys_sparc32.c */
521 ({ unsigned long __ret; \
522 __asm__ ("srl %0, 0, %0" \
529 #ifdef AFS_SPARC64_LINUX_ENV
530 if (test_thread_flag(TIF_32BIT))
532 if (current->thread.flags & SPARC_FLAG_32BIT)
535 AFS_COPYIN((char *)parm4, (char *)eparm32, sizeof(eparm32), code);
536 eparm[0] = AA(eparm32[0]);
537 eparm[1] = AA(eparm32[1]);
538 eparm[2] = AA(eparm32[2]);
542 AFS_COPYIN((char *)parm4, (char *)eparm, sizeof(eparm), code);
543 uap->parm4 = eparm[0];
544 uap->parm5 = eparm[1];
545 uap->parm6 = eparm[2];
552 #if defined(AFS_DARWIN80_ENV)
554 osi_Assert(*retval == 0);
555 #ifdef AFS_DARWIN100_ENV
556 if (proc_is64bit(p)) {
557 uap64 = (struct afssysa64 *)args;
558 if (uap64->syscall == AFSCALL_CALL) {
560 afs_syscall64_call(uap64->parm1, uap64->parm2, uap64->parm3,
561 uap64->parm4, uap64->parm5, uap64->parm6);
562 /* pass back the code as syscall retval */
567 } else if (uap64->syscall == AFSCALL_SETPAG) {
569 code = afs_setpag(p, args, retval);
571 } else if (uap64->syscall == AFSCALL_PIOCTL) {
574 afs_syscall64_pioctl(uap64->parm1, (unsigned int)uap64->parm2,
575 uap64->parm3, (int)uap64->parm4,
578 } else if (uap64->syscall == AFSCALL_ICL) {
581 Afscall64_icl(uap64->parm1, uap64->parm2, uap64->parm3,
582 uap64->parm4, uap64->parm5, retval);
586 if (uap64->syscall != AFSCALL_CALL)
588 } else { /* and the default case for 32 bit procs */
590 uap = (struct afssysa *)args;
592 #if defined(AFS_HPUX_ENV)
594 * There used to be code here (duplicated from osi_Init()) for
595 * initializing the semaphore used by AFS_GLOCK(). Was the
596 * duplication to handle the case of a dynamically loaded kernel
602 #if defined(AFS_NBSD40_ENV)
603 if (SCARG(uap, syscall) == AFSCALL_CALL) {
605 afs_syscall_call(SCARG(uap, parm1), SCARG(uap, parm2),
606 SCARG(uap, parm3), SCARG(uap, parm4),
607 SCARG(uap, parm5), SCARG(uap, parm6));
608 } else if (SCARG(uap, syscall) == AFSCALL_SETPAG) {
610 if (uap->syscall == AFSCALL_CALL) {
612 afs_syscall_call(uap->parm1, uap->parm2, uap->parm3,
613 uap->parm4, uap->parm5, uap->parm6);
614 #ifdef AFS_DARWIN_ENV
615 /* pass back the code as syscall retval */
621 } else if (uap->syscall == AFSCALL_SETPAG) {
626 procp = ttoproc(curthread);
628 code = afs_setpag(&procp->p_cred);
632 #if defined(AFS_FBSD_ENV)
633 code = afs_setpag(p, args);
634 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
635 code = afs_setpag(p, args, retval);
636 #else /* AFS_DARWIN_ENV || AFS_XBSD_ENV */
642 #if defined(AFS_NBSD40_ENV)
643 (SCARG(uap, syscall) == AFSCALL_PIOCTL) {
645 (uap->syscall == AFSCALL_PIOCTL) {
648 #if defined(AFS_SUN5_ENV)
650 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3,
651 uap->parm4, rvp, CRED());
652 #elif defined(AFS_FBSD_ENV)
654 afs_syscall_pioctl((void *)uap->parm1, uap->parm2, (void *)uap->parm3,
655 uap->parm4, p->td_ucred);
656 #elif defined(AFS_DARWIN80_ENV)
658 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3,
659 uap->parm4, kauth_cred_get());
660 #elif defined(AFS_NBSD40_ENV)
662 afs_syscall_pioctl((char *)SCARG(uap, parm1), SCARG(uap, parm2),
663 (void *)SCARG(uap, parm3), SCARG(uap, parm4),
665 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
667 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3,
668 uap->parm4, p->p_cred->pc_ucred);
671 afs_syscall_pioctl((char *)uap->parm1,
672 (unsigned int)uap->parm2,
678 #ifdef AFS_NBSD40_ENV
679 } else if (SCARG(uap, syscall) == AFSCALL_ICREATE) {
680 struct iparam iparams;
681 code = copyin_iparam((char *) SCARG(uap, parm3), &iparams);
683 } else if (uap->syscall == AFSCALL_ICREATE) {
684 struct iparam iparams;
686 code = copyin_iparam((char *)uap->parm3, &iparams);
689 #if defined(KERNEL_HAVE_UERROR)
693 #if defined(AFS_SUN5_ENV)
695 afs_syscall_icreate(uap->parm1, uap->parm2, iparams.param1,
696 iparams.param2, iparams.param3,
697 iparams.param4, rvp, CRED());
698 #elif defined(AFS_NBSD40_ENV)
700 afs_syscall_icreate(SCARG(uap, parm1), SCARG(uap, parm2),
701 iparams.param1, iparams.param2, iparams.param3,
702 iparams.param4, retval
706 afs_syscall_icreate(uap->parm1, uap->parm2, iparams.param1,
707 iparams.param2, iparams.param3,
709 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
713 #endif /* AFS_SUN5_ENV */
715 #if defined(AFS_NBSD40_ENV)
716 } else if (SCARG(uap, syscall) == AFSCALL_IOPEN) {
718 } else if (uap->syscall == AFSCALL_IOPEN) {
719 #endif /* !AFS_NBSD40_ENV */
720 #if defined(AFS_SUN5_ENV)
722 afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3, rvp,
724 #elif defined(AFS_NBSD40_ENV)
725 code = afs_syscall_iopen(SCARG(uap, parm1), SCARG(uap, parm2),
726 SCARG(uap, parm3), retval);
728 code = afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3
729 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
733 #endif /* AFS_SUN5_ENV */
734 #if defined(AFS_NBSD40_ENV)
735 } else if (SCARG(uap, syscall) == AFSCALL_IDEC) {
737 } else if (uap->syscall == AFSCALL_IDEC) {
739 #if defined(AFS_NBSD40_ENV)
740 code = afs_syscall_iincdec(SCARG(uap, parm1), SCARG(uap, parm2),
741 SCARG(uap, parm3), -1);
746 afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, -1
747 #if defined(AFS_SUN5_ENV)
752 #endif /* !AFS_NBSD40_ENV */
753 #if defined(AFS_NBSD40_ENV)
754 } else if (SCARG(uap, syscall) == AFSCALL_IINC) {
756 } else if (uap->syscall == AFSCALL_IINC) {
758 #if defined(AFS_NBSD40_ENV)
759 code = afs_syscall_iincdec(SCARG(uap, parm1), SCARG(uap, parm2),
760 SCARG(uap, parm3), 1);
763 afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, 1
768 #endif /* !AFS_NBSD40_ENV */
769 #if defined(AFS_NBSD40_ENV)
770 } else if (SCARG(uap, syscall) == AFSCALL_ICL) {
772 } else if (uap->syscall == AFSCALL_ICL) {
776 #if defined(AFS_NBSD40_ENV)
777 Afscall_icl(SCARG(uap, parm1), SCARG(uap, parm2),
778 SCARG(uap, parm3), SCARG(uap, parm4),
779 SCARG(uap, parm5), retval);
781 Afscall_icl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
782 uap->parm5, (long *)retval);
783 #endif /* !AFS_NBSD40_ENV */
787 /* ICL commands can return values. */
788 code = -linux_ret; /* Gets negated again at exit below */
792 #if defined(KERNEL_HAVE_UERROR)
796 #endif /* !AFS_LINUX_ENV */
798 #if defined(KERNEL_HAVE_UERROR)
804 #if defined(AFS_DARWIN80_ENV)
805 if (uap->syscall != AFSCALL_CALL)
807 #ifdef AFS_DARWIN100_ENV
816 #endif /* AFS_SGI_ENV */
817 #endif /* !AFS_AIX32_ENV */