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"
16 #include "afs/sysincludes.h" /* Standard vendor system headers */
17 #include "afsincludes.h" /* Afs-based standard headers */
18 #include "afs/afs_stats.h"
19 #include "rx/rx_globals.h"
20 #if !defined(UKERNEL) && !defined(AFS_LINUX20_ENV)
23 #include "h/hashing.h"
25 #if !defined(AFS_HPUX110_ENV) && !defined(AFS_DARWIN60_ENV)
26 #include "netinet/in_var.h"
28 #endif /* !defined(UKERNEL) */
29 #ifdef AFS_LINUX22_ENV
30 #include "h/smp_lock.h"
33 #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)
35 afs_ioctl32_to_afs_ioctl(const struct afs_ioctl32 *src, struct afs_ioctl *dst)
37 dst->in = (char *)(unsigned long)src->in;
38 dst->out = (char *)(unsigned long)src->out;
39 dst->in_size = src->in_size;
40 dst->out_size = src->out_size;
45 * If you need to change copyin_afs_ioctl(), you may also need to change
50 copyin_afs_ioctl(caddr_t cmarg, struct afs_ioctl *dst)
53 #if defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)
54 struct afs_ioctl32 dst32;
57 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
59 afs_ioctl32_to_afs_ioctl(&dst32, dst);
62 #endif /* defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL) */
65 #if defined(AFS_HPUX_64BIT_ENV)
66 struct afs_ioctl32 dst32;
68 if (is_32bit(u.u_procp)) { /* is_32bit() in proc_iface.h */
69 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
71 afs_ioctl32_to_afs_ioctl(&dst32, dst);
74 #endif /* defined(AFS_HPUX_64BIT_ENV) */
76 #if defined(AFS_SUN57_64BIT_ENV)
77 struct afs_ioctl32 dst32;
79 if (get_udatamodel() == DATAMODEL_ILP32) {
80 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
82 afs_ioctl32_to_afs_ioctl(&dst32, dst);
85 #endif /* defined(AFS_SUN57_64BIT_ENV) */
87 #if defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64)
88 struct afs_ioctl32 dst32;
90 if (!ABI_IS_64BIT(get_current_abi())) {
91 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
93 afs_ioctl32_to_afs_ioctl(&dst32, dst);
96 #endif /* defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64) */
98 #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
99 struct afs_ioctl32 dst32;
101 #ifdef AFS_SPARC64_LINUX26_ENV
102 if (test_thread_flag(TIF_32BIT))
103 #elif AFS_SPARC64_LINUX24_ENV
104 if (current->thread.flags & SPARC_FLAG_32BIT)
105 #elif defined(AFS_SPARC64_LINUX20_ENV)
106 if (current->tss.flags & SPARC_FLAG_32BIT)
108 #elif defined(AFS_AMD64_LINUX26_ENV)
109 if (test_thread_flag(TIF_IA32))
110 #elif defined(AFS_AMD64_LINUX20_ENV)
111 if (current->thread.flags & THREAD_IA32)
113 #elif defined(AFS_PPC64_LINUX26_ENV)
114 if (current->thread_info->flags & _TIF_32BIT)
115 #elif defined(AFS_PPC64_LINUX20_ENV)
116 if (current->thread.flags & PPC_FLAG_32BIT)
118 #elif defined(AFS_S390X_LINUX26_ENV)
119 if (test_thread_flag(TIF_31BIT))
120 #elif defined(AFS_S390X_LINUX20_ENV)
121 if (current->thread.flags & S390_FLAG_31BIT)
124 #error pioctl32 not done for this linux
127 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
129 afs_ioctl32_to_afs_ioctl(&dst32, dst);
132 #endif /* defined(AFS_LINUX_64BIT_KERNEL) */
134 AFS_COPYIN(cmarg, (caddr_t) dst, sizeof *dst, code);
141 #include "sys/lockl.h"
144 * syscall - this is the VRMIX system call entry point.
147 * THIS SHOULD BE CHANGED TO afs_syscall(), but requires
148 * all the user-level calls to `syscall' to change.
150 syscall(syscall, p1, p2, p3, p4, p5, p6)
152 register rval1 = 0, code;
155 #ifndef AFS_AIX41_ENV
156 extern lock_t kernel_lock;
157 monster = lockl(&kernel_lock, LOCK_SHORT);
158 #endif /* !AFS_AIX41_ENV */
160 AFS_STATCNT(syscall);
164 rval1 = afs_syscall_call(p1, p2, p3, p4, p5, p6);
169 rval1 = afs_setpag();
175 rval1 = afs_syscall_pioctl(p1, p2, p3, p4);
179 case AFSCALL_ICREATE:
180 rval1 = afs_syscall_icreate(p1, p2, p3, p4, p5, p6);
184 rval1 = afs_syscall_iopen(p1, p2, p3);
188 rval1 = afs_syscall_iincdec(p1, p2, p3, -1);
192 rval1 = afs_syscall_iincdec(p1, p2, p3, 1);
197 code = Afscall_icl(p1, p2, p3, p4, p5, &retval);
212 #ifndef AFS_AIX41_ENV
213 if (monster != LOCK_NEST)
214 unlockl(&kernel_lock);
215 #endif /* !AFS_AIX41_ENV */
216 return getuerror()? -1 : rval1;
220 * lsetpag - interface to afs_setpag().
225 AFS_STATCNT(lsetpag);
226 return syscall(AFSCALL_SETPAG, 0, 0, 0, 0, 0);
230 * lpioctl - interface to pioctl()
232 lpioctl(path, cmd, cmarg, follow)
236 AFS_STATCNT(lpioctl);
237 return syscall(AFSCALL_PIOCTL, path, cmd, cmarg, follow);
240 #else /* !AFS_AIX32_ENV */
242 #if defined(AFS_SGI_ENV)
254 Afs_syscall(struct afsargs *uap, rval_t * rvp)
259 AFS_STATCNT(afs_syscall);
260 switch (uap->syscall) {
265 Afscall_icl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
266 uap->parm5, &retval);
268 rvp->r_val1 = retval;
270 #ifdef AFS_SGI_XFS_IOPS_ENV
273 afs_syscall_idec64(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
278 afs_syscall_iinc64(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
281 case AFSCALL_ILISTINODE64:
283 afs_syscall_ilistinode64(uap->parm1, uap->parm2, uap->parm3,
284 uap->parm4, uap->parm5);
286 case AFSCALL_ICREATENAME64:
288 afs_syscall_icreatename64(uap->parm1, uap->parm2, uap->parm3,
289 uap->parm4, uap->parm5);
292 #ifdef AFS_SGI_VNODE_GLUE
293 case AFSCALL_INIT_KERNEL_CONFIG:
294 error = afs_init_kernel_config(uap->parm1);
299 afs_syscall_call(uap->syscall, uap->parm1, uap->parm2, uap->parm3,
300 uap->parm4, uap->parm5);
305 #else /* AFS_SGI_ENV */
322 #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))
324 iparam32_to_iparam(const struct iparam32 *src, struct iparam *dst)
326 dst->param1 = src->param1;
327 dst->param2 = src->param2;
328 dst->param3 = src->param3;
329 dst->param4 = src->param4;
334 * If you need to change copyin_iparam(), you may also need to change
335 * copyin_afs_ioctl().
339 copyin_iparam(caddr_t cmarg, struct iparam *dst)
343 #if defined(AFS_HPUX_64BIT_ENV)
344 struct iparam32 dst32;
346 if (is_32bit(u.u_procp)) { /* is_32bit() in proc_iface.h */
347 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
349 iparam32_to_iparam(&dst32, dst);
352 #endif /* AFS_HPUX_64BIT_ENV */
354 #if defined(AFS_SUN57_64BIT_ENV)
355 struct iparam32 dst32;
357 if (get_udatamodel() == DATAMODEL_ILP32) {
358 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
360 iparam32_to_iparam(&dst32, dst);
363 #endif /* AFS_SUN57_64BIT_ENV */
365 #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
366 struct iparam32 dst32;
368 #ifdef AFS_SPARC64_LINUX26_ENV
369 if (test_thread_flag(TIF_32BIT))
370 #elif AFS_SPARC64_LINUX24_ENV
371 if (current->thread.flags & SPARC_FLAG_32BIT)
372 #elif defined(AFS_SPARC64_LINUX20_ENV)
373 if (current->tss.flags & SPARC_FLAG_32BIT)
375 #elif defined(AFS_AMD64_LINUX26_ENV)
376 if (test_thread_flag(TIF_IA32))
377 #elif defined(AFS_AMD64_LINUX20_ENV)
378 if (current->thread.flags & THREAD_IA32)
380 #elif defined(AFS_PPC64_LINUX26_ENV)
381 if (current->thread_info->flags & _TIF_32BIT)
382 #elif defined(AFS_PPC64_LINUX20_ENV)
383 if (current->thread.flags & PPC_FLAG_32BIT)
385 #elif defined(AFS_S390X_LINUX26_ENV)
386 if (test_thread_flag(TIF_31BIT))
387 #elif defined(AFS_S390X_LINUX20_ENV)
388 if (current->thread.flags & S390_FLAG_31BIT)
391 #error iparam32 not done for this linux platform
394 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
396 iparam32_to_iparam(&dst32, dst);
399 #endif /* AFS_LINUX_64BIT_KERNEL */
401 AFS_COPYIN(cmarg, (caddr_t) dst, sizeof *dst, code);
405 /* Main entry of all afs system calls */
407 extern int afs_sinited;
409 /** The 32 bit OS expects the members of this structure to be 32 bit
410 * quantities and the 64 bit OS expects them as 64 bit quanties. Hence
411 * to accomodate both, *long* is used instead of afs_int32
436 Afs_syscall(register struct afssysa *uap, rval_t * rvp)
438 int *retval = &rvp->r_val1;
439 #else /* AFS_SUN5_ENV */
440 #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
442 afs3_syscall(p, args, retval)
443 #ifdef AFS_FBSD50_ENV
459 } *uap = (struct a *)args;
460 #else /* AFS_OSF_ENV */
461 #ifdef AFS_LINUX20_ENV
469 long parm6; /* not actually used - should be removed */
471 /* Linux system calls only set up for 5 arguments. */
473 afs_syscall(long syscall, long parm1, long parm2, long parm3, long parm4)
475 struct afssysargs args, *uap = &args;
477 long *retval = &linux_ret;
478 long eparm[4]; /* matches AFSCALL_ICL in fstrace.c */
479 #ifdef AFS_SPARC64_LINUX24_ENV
480 afs_int32 eparm32[4];
482 /* eparm is also used by AFSCALL_CALL in afsd.c */
495 } *uap = (struct a *)u.u_ap;
508 } *uap = (struct a *)u.u_ap;
510 #if defined(AFS_HPUX_ENV)
511 long *retval = &u.u_rval1;
513 int *retval = &u.u_rval1;
515 #endif /* AFS_LINUX20_ENV */
516 #endif /* AFS_OSF_ENV */
517 #endif /* AFS_SUN5_ENV */
518 register int code = 0;
520 AFS_STATCNT(afs_syscall);
527 #ifdef AFS_LINUX20_ENV
529 /* setup uap for use below - pull out the magic decoder ring to know
530 * which syscalls have folded argument lists.
532 uap->syscall = syscall;
536 if (syscall == AFSCALL_ICL || syscall == AFSCALL_CALL) {
537 #ifdef AFS_SPARC64_LINUX24_ENV
538 /* from arch/sparc64/kernel/sys_sparc32.c */
540 ({ unsigned long __ret; \
541 __asm__ ("srl %0, 0, %0" \
548 #ifdef AFS_SPARC64_LINUX26_ENV
549 if (test_thread_flag(TIF_32BIT))
551 if (current->thread.flags & SPARC_FLAG_32BIT)
554 AFS_COPYIN((char *)parm4, (char *)eparm32, sizeof(eparm32), code);
555 eparm[0] = AA(eparm32[0]);
556 eparm[1] = AA(eparm32[1]);
557 eparm[2] = AA(eparm32[2]);
561 AFS_COPYIN((char *)parm4, (char *)eparm, sizeof(eparm), code);
562 uap->parm4 = eparm[0];
563 uap->parm5 = eparm[1];
564 uap->parm6 = eparm[2];
571 #if defined(AFS_DARWIN80_ENV)
573 osi_Assert(*retval == 0);
575 #if defined(AFS_HPUX_ENV)
577 * There used to be code here (duplicated from osi_Init()) for
578 * initializing the semaphore used by AFS_GLOCK(). Was the
579 * duplication to handle the case of a dynamically loaded kernel
584 if (uap->syscall == AFSCALL_CALL) {
587 afs_syscall_call(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
588 uap->parm5, uap->parm6, rvp, CRED());
591 afs_syscall_call(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
592 uap->parm5, uap->parm6);
594 } else if (uap->syscall == AFSCALL_SETPAG) {
596 register proc_t *procp;
598 procp = ttoproc(curthread);
600 code = afs_setpag(&procp->p_cred);
604 #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
605 code = afs_setpag(p, args, retval);
606 #else /* AFS_OSF_ENV */
611 } else if (uap->syscall == AFSCALL_PIOCTL) {
613 #if defined(AFS_SUN5_ENV)
615 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
617 #elif defined(AFS_FBSD50_ENV)
619 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
621 #elif defined(AFS_DARWIN80_ENV)
623 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
625 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
627 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
628 p->p_cred->pc_ucred);
631 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3,
635 } else if (uap->syscall == AFSCALL_ICREATE) {
636 struct iparam iparams;
638 code = copyin_iparam((char *)uap->parm3, &iparams);
640 #if defined(KERNEL_HAVE_UERROR)
646 afs_syscall_icreate(uap->parm1, uap->parm2, iparams.param1,
647 iparams.param2, iparams.param3,
648 iparams.param4, rvp, CRED());
651 afs_syscall_icreate(uap->parm1, uap->parm2, iparams.param1,
653 #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
654 iparams.param3, iparams.param4, retval);
656 iparams.param3, iparams.param4);
658 #endif /* AFS_SUN5_ENV */
659 } else if (uap->syscall == AFSCALL_IOPEN) {
662 afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3, rvp,
665 #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
666 code = afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3, retval);
668 code = afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3);
670 #endif /* AFS_SUN5_ENV */
671 } else if (uap->syscall == AFSCALL_IDEC) {
674 afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, -1, rvp,
677 code = afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, -1);
678 #endif /* AFS_SUN5_ENV */
679 } else if (uap->syscall == AFSCALL_IINC) {
682 afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, 1, rvp,
685 code = afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, 1);
686 #endif /* AFS_SUN5_ENV */
687 } else if (uap->syscall == AFSCALL_ICL) {
690 Afscall_icl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
693 #ifdef AFS_LINUX20_ENV
695 /* ICL commands can return values. */
696 code = -linux_ret; /* Gets negated again at exit below */
700 #if defined(KERNEL_HAVE_UERROR)
704 #endif /* !AFS_LINUX20_ENV */
706 #if defined(KERNEL_HAVE_UERROR)
713 #if defined(AFS_DARWIN80_ENV)
716 #ifdef AFS_LINUX20_ENV
722 #endif /* AFS_SGI_ENV */
723 #endif /* !AFS_AIX32_ENV */