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 defined(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 defined(STRUCT_TASK_STRUCT_HAS_THREAD_INFO)
115 if (current->thread_info->flags & _TIF_32BIT)
117 if (task_thread_info(current)->flags & _TIF_32BIT)
119 #elif defined(AFS_PPC64_LINUX20_ENV)
120 if (current->thread.flags & PPC_FLAG_32BIT)
122 #elif defined(AFS_S390X_LINUX26_ENV)
123 if (test_thread_flag(TIF_31BIT))
124 #elif defined(AFS_S390X_LINUX20_ENV)
125 if (current->thread.flags & S390_FLAG_31BIT)
128 #error pioctl32 not done for this linux
131 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
133 afs_ioctl32_to_afs_ioctl(&dst32, dst);
136 #endif /* defined(AFS_LINUX_64BIT_KERNEL) */
138 AFS_COPYIN(cmarg, (caddr_t) dst, sizeof *dst, code);
145 #include "sys/lockl.h"
148 * syscall - this is the VRMIX system call entry point.
151 * THIS SHOULD BE CHANGED TO afs_syscall(), but requires
152 * all the user-level calls to `syscall' to change.
154 syscall(syscall, p1, p2, p3, p4, p5, p6)
156 register rval1 = 0, code;
159 #ifndef AFS_AIX41_ENV
160 extern lock_t kernel_lock;
161 monster = lockl(&kernel_lock, LOCK_SHORT);
162 #endif /* !AFS_AIX41_ENV */
164 AFS_STATCNT(syscall);
168 rval1 = afs_syscall_call(p1, p2, p3, p4, p5, p6);
173 rval1 = afs_setpag();
179 rval1 = afs_syscall_pioctl(p1, p2, p3, p4);
183 case AFSCALL_ICREATE:
184 rval1 = afs_syscall_icreate(p1, p2, p3, p4, p5, p6);
188 rval1 = afs_syscall_iopen(p1, p2, p3);
192 rval1 = afs_syscall_iincdec(p1, p2, p3, -1);
196 rval1 = afs_syscall_iincdec(p1, p2, p3, 1);
201 code = Afscall_icl(p1, p2, p3, p4, p5, &retval);
216 #ifndef AFS_AIX41_ENV
217 if (monster != LOCK_NEST)
218 unlockl(&kernel_lock);
219 #endif /* !AFS_AIX41_ENV */
220 return getuerror()? -1 : rval1;
224 * lsetpag - interface to afs_setpag().
229 AFS_STATCNT(lsetpag);
230 return syscall(AFSCALL_SETPAG, 0, 0, 0, 0, 0);
234 * lpioctl - interface to pioctl()
236 lpioctl(path, cmd, cmarg, follow)
240 AFS_STATCNT(lpioctl);
241 return syscall(AFSCALL_PIOCTL, path, cmd, cmarg, follow);
244 #else /* !AFS_AIX32_ENV */
246 #if defined(AFS_SGI_ENV)
258 Afs_syscall(struct afsargs *uap, rval_t * rvp)
263 AFS_STATCNT(afs_syscall);
264 switch (uap->syscall) {
269 Afscall_icl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
270 uap->parm5, &retval);
272 rvp->r_val1 = retval;
274 #ifdef AFS_SGI_XFS_IOPS_ENV
277 afs_syscall_idec64(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
282 afs_syscall_iinc64(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
285 case AFSCALL_ILISTINODE64:
287 afs_syscall_ilistinode64(uap->parm1, uap->parm2, uap->parm3,
288 uap->parm4, uap->parm5);
290 case AFSCALL_ICREATENAME64:
292 afs_syscall_icreatename64(uap->parm1, uap->parm2, uap->parm3,
293 uap->parm4, uap->parm5);
296 #ifdef AFS_SGI_VNODE_GLUE
297 case AFSCALL_INIT_KERNEL_CONFIG:
298 error = afs_init_kernel_config(uap->parm1);
303 afs_syscall_call(uap->syscall, uap->parm1, uap->parm2, uap->parm3,
304 uap->parm4, uap->parm5);
309 #else /* AFS_SGI_ENV */
326 #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))
328 iparam32_to_iparam(const struct iparam32 *src, struct iparam *dst)
330 dst->param1 = src->param1;
331 dst->param2 = src->param2;
332 dst->param3 = src->param3;
333 dst->param4 = src->param4;
338 * If you need to change copyin_iparam(), you may also need to change
339 * copyin_afs_ioctl().
343 copyin_iparam(caddr_t cmarg, struct iparam *dst)
347 #if defined(AFS_HPUX_64BIT_ENV)
348 struct iparam32 dst32;
350 if (is_32bit(u.u_procp)) { /* is_32bit() in proc_iface.h */
351 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
353 iparam32_to_iparam(&dst32, dst);
356 #endif /* AFS_HPUX_64BIT_ENV */
358 #if defined(AFS_SUN57_64BIT_ENV)
359 struct iparam32 dst32;
361 if (get_udatamodel() == DATAMODEL_ILP32) {
362 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
364 iparam32_to_iparam(&dst32, dst);
367 #endif /* AFS_SUN57_64BIT_ENV */
369 #if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV)
370 struct iparam32 dst32;
372 #ifdef AFS_SPARC64_LINUX26_ENV
373 if (test_thread_flag(TIF_32BIT))
374 #elif defined(AFS_SPARC64_LINUX24_ENV)
375 if (current->thread.flags & SPARC_FLAG_32BIT)
376 #elif defined(AFS_SPARC64_LINUX20_ENV)
377 if (current->tss.flags & SPARC_FLAG_32BIT)
379 #elif defined(AFS_AMD64_LINUX26_ENV)
380 if (test_thread_flag(TIF_IA32))
381 #elif defined(AFS_AMD64_LINUX20_ENV)
382 if (current->thread.flags & THREAD_IA32)
384 #elif defined(AFS_PPC64_LINUX26_ENV)
385 #if defined(STRUCT_TASK_STRUCT_HAS_THREAD_INFO)
386 if (current->thread_info->flags & _TIF_32BIT)
388 if (task_thread_info(current)->flags & _TIF_32BIT)
390 #elif defined(AFS_PPC64_LINUX20_ENV)
391 if (current->thread.flags & PPC_FLAG_32BIT)
393 #elif defined(AFS_S390X_LINUX26_ENV)
394 if (test_thread_flag(TIF_31BIT))
395 #elif defined(AFS_S390X_LINUX20_ENV)
396 if (current->thread.flags & S390_FLAG_31BIT)
399 #error iparam32 not done for this linux platform
402 AFS_COPYIN(cmarg, (caddr_t) & dst32, sizeof dst32, code);
404 iparam32_to_iparam(&dst32, dst);
407 #endif /* AFS_LINUX_64BIT_KERNEL */
409 AFS_COPYIN(cmarg, (caddr_t) dst, sizeof *dst, code);
413 /* Main entry of all afs system calls */
415 extern int afs_sinited;
417 /** The 32 bit OS expects the members of this structure to be 32 bit
418 * quantities and the 64 bit OS expects them as 64 bit quanties. Hence
419 * to accomodate both, *long* is used instead of afs_int32
444 Afs_syscall(register struct afssysa *uap, rval_t * rvp)
446 int *retval = &rvp->r_val1;
447 #else /* AFS_SUN5_ENV */
448 #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
450 afs3_syscall(p, args, retval)
451 #ifdef AFS_FBSD50_ENV
467 } *uap = (struct a *)args;
468 #else /* AFS_OSF_ENV */
469 #ifdef AFS_LINUX20_ENV
477 long parm6; /* not actually used - should be removed */
479 /* Linux system calls only set up for 5 arguments. */
481 afs_syscall(long syscall, long parm1, long parm2, long parm3, long parm4)
483 struct afssysargs args, *uap = &args;
485 long *retval = &linux_ret;
486 long eparm[4]; /* matches AFSCALL_ICL in fstrace.c */
487 #ifdef AFS_SPARC64_LINUX24_ENV
488 afs_int32 eparm32[4];
490 /* 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(uap->parm1, uap->parm2, 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 */