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"
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)
21 #include "h/hashing.h"
23 #if !defined(AFS_HPUX110_ENV) && !defined(AFS_DARWIN60_ENV)
24 #include "netinet/in_var.h"
26 #endif /* !defined(UKERNEL) */
27 #ifdef AFS_LINUX22_ENV
28 #include "h/smp_lock.h"
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)
33 afs_ioctl32_to_afs_ioctl(const struct afs_ioctl32 *src, struct afs_ioctl *dst)
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;
43 * If you need to change copyin_afs_ioctl(), you may also need to change
48 copyin_afs_ioctl(caddr_t cmarg, struct afs_ioctl *dst)
51 #if defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)
52 struct afs_ioctl32 dst32;
55 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
57 afs_ioctl32_to_afs_ioctl(&dst32, dst);
60 #endif /* defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL) */
63 #if defined(AFS_HPUX_64BIT_ENV)
64 struct afs_ioctl32 dst32;
66 if (is_32bit(u.u_procp)) { /* is_32bit() in proc_iface.h */
67 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
69 afs_ioctl32_to_afs_ioctl(&dst32, dst);
72 #endif /* defined(AFS_HPUX_64BIT_ENV) */
74 #if defined(AFS_SUN57_64BIT_ENV)
75 struct afs_ioctl32 dst32;
77 if (get_udatamodel() == DATAMODEL_ILP32) {
78 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
80 afs_ioctl32_to_afs_ioctl(&dst32, dst);
83 #endif /* defined(AFS_SUN57_64BIT_ENV) */
85 #if defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64)
86 struct afs_ioctl32 dst32;
88 if (!ABI_IS_64BIT(get_current_abi())) {
89 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
91 afs_ioctl32_to_afs_ioctl(&dst32, dst);
94 #endif /* defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64) */
96 #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
97 struct afs_ioctl32 dst32;
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)
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)
111 #elif defined(AFS_PPC64_LINUX26_ENV)
112 #if defined(STRUCT_TASK_STRUCT_HAS_THREAD_INFO)
113 if (current->thread_info->flags & _TIF_32BIT)
115 if (task_thread_info(current)->flags & _TIF_32BIT)
117 #elif defined(AFS_PPC64_LINUX20_ENV)
118 if (current->thread.flags & PPC_FLAG_32BIT)
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)
126 #error pioctl32 not done for this linux
129 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
131 afs_ioctl32_to_afs_ioctl(&dst32, dst);
134 #endif /* defined(AFS_LINUX_64BIT_KERNEL) */
136 AFS_COPYIN(cmarg, (caddr_t) dst, sizeof *dst, code);
143 #include "sys/lockl.h"
146 * syscall - this is the VRMIX system call entry point.
149 * THIS SHOULD BE CHANGED TO afs_syscall(), but requires
150 * all the user-level calls to `syscall' to change.
152 syscall(syscall, p1, p2, p3, p4, p5, p6)
154 register rval1 = 0, code;
157 #ifndef AFS_AIX41_ENV
158 extern lock_t kernel_lock;
159 monster = lockl(&kernel_lock, LOCK_SHORT);
160 #endif /* !AFS_AIX41_ENV */
162 AFS_STATCNT(syscall);
166 rval1 = afs_syscall_call(p1, p2, p3, p4, p5, p6);
171 rval1 = afs_setpag();
177 rval1 = afs_syscall_pioctl(p1, p2, p3, p4);
181 case AFSCALL_ICREATE:
182 rval1 = afs_syscall_icreate(p1, p2, p3, p4, p5, p6);
186 rval1 = afs_syscall_iopen(p1, p2, p3);
190 rval1 = afs_syscall_iincdec(p1, p2, p3, -1);
194 rval1 = afs_syscall_iincdec(p1, p2, p3, 1);
199 code = Afscall_icl(p1, p2, p3, p4, p5, &retval);
214 #ifndef AFS_AIX41_ENV
215 if (monster != LOCK_NEST)
216 unlockl(&kernel_lock);
217 #endif /* !AFS_AIX41_ENV */
218 return getuerror()? -1 : rval1;
222 * lsetpag - interface to afs_setpag().
228 AFS_STATCNT(lsetpag);
229 return syscall(AFSCALL_SETPAG, 0, 0, 0, 0, 0);
233 * lpioctl - interface to pioctl()
236 lpioctl(char *path, int cmd, void *cmarg, int follow)
239 AFS_STATCNT(lpioctl);
240 return syscall(AFSCALL_PIOCTL, path, cmd, cmarg, follow);
243 #else /* !AFS_AIX32_ENV */
245 #if defined(AFS_SGI_ENV)
257 Afs_syscall(struct afsargs *uap, rval_t * rvp)
262 AFS_STATCNT(afs_syscall);
263 switch (uap->syscall) {
268 Afscall_icl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
269 uap->parm5, &retval);
271 rvp->r_val1 = retval;
273 #ifdef AFS_SGI_XFS_IOPS_ENV
276 afs_syscall_idec64(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
281 afs_syscall_iinc64(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
284 case AFSCALL_ILISTINODE64:
286 afs_syscall_ilistinode64(uap->parm1, uap->parm2, uap->parm3,
287 uap->parm4, uap->parm5);
289 case AFSCALL_ICREATENAME64:
291 afs_syscall_icreatename64(uap->parm1, uap->parm2, uap->parm3,
292 uap->parm4, uap->parm5);
295 #ifdef AFS_SGI_VNODE_GLUE
296 case AFSCALL_INIT_KERNEL_CONFIG:
297 error = afs_init_kernel_config(uap->parm1);
302 afs_syscall_call(uap->syscall, uap->parm1, uap->parm2, uap->parm3,
303 uap->parm4, uap->parm5);
308 #else /* AFS_SGI_ENV */
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))
327 iparam32_to_iparam(const struct iparam32 *src, struct iparam *dst)
329 dst->param1 = src->param1;
330 dst->param2 = src->param2;
331 dst->param3 = src->param3;
332 dst->param4 = src->param4;
337 * If you need to change copyin_iparam(), you may also need to change
338 * copyin_afs_ioctl().
342 copyin_iparam(caddr_t cmarg, struct iparam *dst)
346 #if defined(AFS_HPUX_64BIT_ENV)
347 struct iparam32 dst32;
349 if (is_32bit(u.u_procp)) { /* is_32bit() in proc_iface.h */
350 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
352 iparam32_to_iparam(&dst32, dst);
355 #endif /* AFS_HPUX_64BIT_ENV */
357 #if defined(AFS_SUN57_64BIT_ENV)
358 struct iparam32 dst32;
360 if (get_udatamodel() == DATAMODEL_ILP32) {
361 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
363 iparam32_to_iparam(&dst32, dst);
366 #endif /* AFS_SUN57_64BIT_ENV */
368 #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
369 struct iparam32 dst32;
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)
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)
383 #elif defined(AFS_PPC64_LINUX26_ENV)
384 #if defined(STRUCT_TASK_STRUCT_HAS_THREAD_INFO)
385 if (current->thread_info->flags & _TIF_32BIT)
387 if (task_thread_info(current)->flags & _TIF_32BIT)
389 #elif defined(AFS_PPC64_LINUX20_ENV)
390 if (current->thread.flags & PPC_FLAG_32BIT)
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)
398 #error iparam32 not done for this linux platform
401 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
403 iparam32_to_iparam(&dst32, dst);
406 #endif /* AFS_LINUX_64BIT_KERNEL */
408 AFS_COPYIN(cmarg, (caddr_t) dst, sizeof *dst, code);
412 /* Main entry of all afs system calls */
414 extern int afs_sinited;
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
443 Afs_syscall(register struct afssysa *uap, rval_t * rvp)
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)
449 afs3_syscall(p, args, retval)
450 #ifdef AFS_FBSD50_ENV
466 } *uap = (struct a *)args;
467 #else /* AFS_OSF_ENV */
468 #ifdef AFS_LINUX20_ENV
476 long parm6; /* not actually used - should be removed */
478 /* Linux system calls only set up for 5 arguments. */
480 afs_syscall(long syscall, long parm1, long parm2, long parm3, long parm4)
482 struct afssysargs args, *uap = &args;
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];
489 /* eparm is also used by AFSCALL_CALL in afsd.c */
503 } *uap = (struct a *)u.u_ap;
516 } *uap = (struct a *)u.u_ap;
518 #if defined(AFS_HPUX_ENV)
519 long *retval = &u.u_rval1;
521 int *retval = &u.u_rval1;
523 #endif /* AFS_LINUX20_ENV */
524 #endif /* AFS_OSF_ENV */
525 #endif /* AFS_SUN5_ENV */
526 register int code = 0;
528 AFS_STATCNT(afs_syscall);
535 #ifdef AFS_LINUX20_ENV
537 /* setup uap for use below - pull out the magic decoder ring to know
538 * which syscalls have folded argument lists.
540 uap->syscall = syscall;
544 if (syscall == AFSCALL_ICL || syscall == AFSCALL_CALL) {
545 #ifdef AFS_SPARC64_LINUX24_ENV
546 /* from arch/sparc64/kernel/sys_sparc32.c */
548 ({ unsigned long __ret; \
549 __asm__ ("srl %0, 0, %0" \
556 #ifdef AFS_SPARC64_LINUX26_ENV
557 if (test_thread_flag(TIF_32BIT))
559 if (current->thread.flags & SPARC_FLAG_32BIT)
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]);
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];
579 #if defined(AFS_DARWIN80_ENV)
581 osi_Assert(*retval == 0);
583 #if defined(AFS_HPUX_ENV)
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
592 if (uap->syscall == AFSCALL_CALL) {
594 afs_syscall_call(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
595 uap->parm5, uap->parm6);
596 } else if (uap->syscall == AFSCALL_SETPAG) {
598 register proc_t *procp;
600 procp = ttoproc(curthread);
602 code = afs_setpag(&procp->p_cred);
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 */
613 } else if (uap->syscall == AFSCALL_PIOCTL) {
615 #if defined(AFS_SUN5_ENV)
617 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
619 #elif defined(AFS_FBSD50_ENV)
621 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
623 #elif defined(AFS_DARWIN80_ENV)
625 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
627 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
629 afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
630 p->p_cred->pc_ucred);
633 afs_syscall_pioctl((char *)uap->parm1, (unsigned int)uap->parm2, (caddr_t)uap->parm3,
637 } else if (uap->syscall == AFSCALL_ICREATE) {
638 struct iparam iparams;
640 code = copyin_iparam((char *)uap->parm3, &iparams);
642 #if defined(KERNEL_HAVE_UERROR)
648 afs_syscall_icreate(uap->parm1, uap->parm2, iparams.param1,
649 iparams.param2, iparams.param3,
650 iparams.param4, rvp, CRED());
653 afs_syscall_icreate(uap->parm1, uap->parm2, iparams.param1,
655 #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
656 iparams.param3, iparams.param4, retval);
658 iparams.param3, iparams.param4);
660 #endif /* AFS_SUN5_ENV */
661 } else if (uap->syscall == AFSCALL_IOPEN) {
664 afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3, rvp,
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);
670 code = afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3);
672 #endif /* AFS_SUN5_ENV */
673 } else if (uap->syscall == AFSCALL_IDEC) {
676 afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, -1, rvp,
679 code = afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, -1);
680 #endif /* AFS_SUN5_ENV */
681 } else if (uap->syscall == AFSCALL_IINC) {
684 afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, 1, rvp,
687 code = afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, 1);
688 #endif /* AFS_SUN5_ENV */
689 } else if (uap->syscall == AFSCALL_ICL) {
692 Afscall_icl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
695 #ifdef AFS_LINUX20_ENV
697 /* ICL commands can return values. */
698 code = -linux_ret; /* Gets negated again at exit below */
702 #if defined(KERNEL_HAVE_UERROR)
706 #endif /* !AFS_LINUX20_ENV */
708 #if defined(KERNEL_HAVE_UERROR)
715 #if defined(AFS_DARWIN80_ENV)
716 if (uap->syscall != AFSCALL_CALL)
719 #ifdef AFS_LINUX20_ENV
725 #endif /* AFS_SGI_ENV */
726 #endif /* !AFS_AIX32_ENV */