/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ #ifndef _AFS_OSI_ #define _AFS_OSI_ #include "h/types.h" #include "h/param.h" #ifdef AFS_LINUX20_ENV #ifndef _LINUX_CODA_FS_I #define _LINUX_CODA_FS_I #define _CODA_HEADER_ struct coda_inode_info {}; #endif #ifndef _LINUX_XFS_FS_I #define _LINUX_XFS_FS_I struct xfs_inode_info {}; #endif #include "h/fs.h" #include "h/mm.h" #endif /* this is just a dummy type decl, we're really using struct sockets here */ struct osi_socket { int junk; }; struct osi_stat { afs_int32 size; /* file size in bytes */ afs_int32 blksize; /* optimal transfer size in bytes */ afs_int32 mtime; /* modification date */ afs_int32 atime; /* access time */ }; struct osi_file { afs_int32 size; /* file size in bytes XXX Must be first field XXX */ #ifdef AFS_LINUX22_ENV struct dentry dentry; /* merely to hold the pointer to the inode. */ struct file file; /* May need this if we really open the file. */ #else struct vnode *vnode; #endif #if defined(AFS_HPUX102_ENV) k_off_t offset; #else afs_int32 offset; #endif int (*proc)(struct osi_file *afile, afs_int32 code); /* proc, which, if not null, is called on writes */ char *rock; /* rock passed to proc */ ino_t inum; /* guarantee validity of hint */ #if defined(UKERNEL) int fd; /* file descriptor for user space files */ #endif /* defined(UKERNEL) */ }; struct osi_dev { #ifdef AFS_OBSD_ENV struct mount *mp; struct vnode *held_vnode; #else afs_int32 dev; #endif }; struct afs_osi_WaitHandle { caddr_t proc; /* process waiting */ }; #define osi_SetFileProc(x,p) ((x)->proc=(p)) #define osi_SetFileRock(x,r) ((x)->rock=(r)) #define osi_GetFileProc(x) ((x)->proc) #define osi_GetFileRock(x) ((x)->rock) #ifdef AFS_TEXT_ENV #define osi_FlushText(vp) if (hcmp((vp)->m.DataVersion, (vp)->flushDV) > 0) \ osi_FlushText_really(vp) #else #define osi_FlushText(vp) #endif #define AFSOP_STOP_RXEVENT 214 /* stop rx event deamon */ #define AFSOP_STOP_COMPLETE 215 /* afs has been shutdown */ #define AFSOP_STOP_RXK_LISTENER 217 /* stop rx listener daemon */ #define osi_NPACKETS 20 /* number of cluster pkts to alloc */ /* * Alloc declarations. */ #define afs_osi_Alloc_NoSleep afs_osi_Alloc /* * Vnode related macros */ #ifndef AFS_OBSD_ENV #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) extern int (**afs_vnodeop_p)(); #define IsAfsVnode(vc) ((vc)->v_op == afs_vnodeop_p) #define SetAfsVnode(vc) (vc)->v_op = afs_vnodeop_p #else extern struct vnodeops *afs_ops; #define IsAfsVnode(vc) ((vc)->v_op == afs_ops) #define SetAfsVnode(vc) (vc)->v_op = afs_ops #endif #define vType(vc) (vc)->v.v_type #define vSetType(vc,type) (vc)->v.v_type = (type) #define vSetVfsp(vc,vfsp) (vc)->v.v_vfsp = (vfsp) #endif #ifdef AFS_SGI65_ENV #define gop_lookupname(fnamep,segflg,followlink,dirvpp,compvpp) \ lookupname((fnamep),(segflg),(followlink),(dirvpp),(compvpp),\ NULL) #else #ifndef AFS_OBSD_ENV #define gop_lookupname(fnamep,segflg,followlink,dirvpp,compvpp) \ lookupname((fnamep),(segflg),(followlink),(dirvpp),(compvpp)) #endif #endif /* * In IRIX 6.5 we cannot have DEBUG turned on since certain * system-defined structures are a different size with DEBUG on, the * kernel is compiled without DEBUG on, and the resulting differences * would break our ability to interact with the rest of the kernel. * * Is DEBUG only for turning the ASSERT() macro? If so, we should * be able to eliminate DEBUG entirely. */ #if !defined(AFS_SGI65_ENV) #ifndef DEBUG #define DEBUG 1 /* Default is to enable debugging/logging */ #endif #endif /* * Time related macros */ #define osi_GetuTime(x) osi_GetTime(x) /* osi_timeval_t exists because SGI 6.x has two sizes of timeval. */ /** In 64 bit Solaris the timeval structure has members that are 64 bit * In the GetTime() interface we expect pointers to afs_int32. So the need to * define osi_timeval_t to have 32 bit members. To make this less ambiguous * we now use 32 bit quantities consistently all over the code. * In 64 bit HP-UX the timeval structure has a 64 bit member. */ #if defined(AFS_HPUX_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_LINUX_64BIT_KERNEL) || (defined(AFS_SGI61_ENV) && defined(KERNEL) && defined(_K64U64)) typedef struct { afs_int32 tv_sec; afs_int32 tv_usec; } osi_timeval_t; #else typedef struct timeval osi_timeval_t; #endif /* AFS_SGI61_ENV */ /* * The following three routines provide the fid routines used by the buffer * and directory packages. */ #define dirp_Zap(afid) (*(afid) = -1) #define dirp_Eq(afid, bfid) (*(afid) == *(bfid)) #define dirp_Cpy(dfid,sfid) (*(dfid) = *(sfid)) /* * osi_ThreadUnique() should yield a value that can be found in ps * output in order to draw correspondences between ICL traces and what * is going on in the system. So if ps cannot show thread IDs it is * likely to be the process ID instead. */ #define osi_ThreadUnique() getpid() #ifdef AFS_GLOBAL_SUNLOCK #define AFS_ASSERT_GLOCK() \ (ISAFS_GLOCK() || (osi_Panic("afs global lock not held at %s:%d\n", __FILE__, __LINE__), 0)) #define AFS_ASSERT_RXGLOCK() \ (ISAFS_RXGLOCK() || (osi_Panic("rx global lock not held at %s:%d\n", __FILE__, __LINE__), 0)) #endif /* AFS_GLOBAL_SUNLOCK */ #ifdef RX_ENABLE_LOCKS #define RX_AFS_GLOCK() AFS_GLOCK() #define RX_AFS_GUNLOCK() AFS_GUNLOCK() #else #define RX_AFS_GLOCK() #define RX_AFS_GUNLOCK() #endif #ifndef KERNEL #define AFS_GLOCK() #define AFS_GUNLOCK() #define ISAFS_GLOCK() 1 #define AFS_ASSERT_GLOCK() #define AFS_RXGLOCK() #define AFS_RXGUNLOCK() #define ISAFS_RXGLOCK() 1 #define AFS_ASSERT_RXGLOCK() #endif /* On an MP that uses multithreading, splnet is not sufficient to provide * mutual exclusion because the other processors will not see it. On some * early multiprocessors (SunOS413 & SGI5.2) splnet actually obtains a global * mutex, which this works in the UP expected way, it means that the whole MP * can only take one interrupt at a time; a serious performance penalty. */ #if ((defined(AFS_GLOBAL_SUNLOCK) || defined(RX_ENABLE_LOCKS)) && !defined(AFS_HPUX_ENV)) || !defined(KERNEL) #define SPLVAR #define NETPRI #define USERPRI #endif #ifndef AFS_OBSD_ENV /* * vnode/vcache ref count manipulation */ #if defined(UKERNEL) #define AFS_RELE(vp) do { VN_RELE(vp); } while (0) #else /* defined(UKERNEL) */ #define AFS_RELE(vp) do { AFS_GUNLOCK(); VN_RELE(vp); AFS_GLOCK(); } while (0) #endif /* defined(UKERNEL) */ #endif /* * For some reason we do bare refcount manipulation in some places, for some * platforms. The assumption is apparently that either we wouldn't call * afs_inactive anyway (because we know the ref count is high), or that it's * OK not to call it (because we don't expect CUnlinked or CDirty). * (Also, of course, the vnode is assumed to be one of ours. Can't use this * macro for V-file vnodes.) */ #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) /* Bare refcount manipulation would probably work on this platform, but just calling VREF does not */ #define AFS_FAST_HOLD(vp) osi_vnhold((vp),0) #else #define AFS_FAST_HOLD(vp) VN_HOLD(&(vp)->v) #endif #define AFS_FAST_RELE(vp) AFS_RELE(AFSTOV(vp)) /* * MP safe versions of routines to copy memory between user space * and kernel space. Call these to avoid taking page faults while * holding the global lock. */ #ifdef AFS_GLOBAL_SUNLOCK #define AFS_COPYIN(SRC,DST,LEN,CODE) \ do { \ int haveGlock = ISAFS_GLOCK(); \ if (haveGlock) \ AFS_GUNLOCK(); \ CODE = copyin((SRC),(DST),(LEN)); \ if (haveGlock) \ AFS_GLOCK(); \ } while(0) #define AFS_COPYINSTR(SRC,DST,LEN,CNT,CODE) \ do { \ int haveGlock = ISAFS_GLOCK(); \ if (haveGlock) \ AFS_GUNLOCK(); \ CODE = copyinstr((SRC),(DST),(LEN),(CNT)); \ if (haveGlock) \ AFS_GLOCK(); \ } while(0) #define AFS_COPYOUT(SRC,DST,LEN,CODE) \ do { \ int haveGlock = ISAFS_GLOCK(); \ if (haveGlock) \ AFS_GUNLOCK(); \ CODE = copyout((SRC),(DST),(LEN)); \ if (haveGlock) \ AFS_GLOCK(); \ } while(0) #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ do { \ int haveGlock = ISAFS_GLOCK(); \ if (haveGlock) \ AFS_GUNLOCK(); \ (UIO)->uio_rw = (RW); \ CODE = uiomove((SRC),(LEN),(UIO)); \ if (haveGlock) \ AFS_GLOCK(); \ } while(0) #else #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ do { \ int haveGlock = ISAFS_GLOCK(); \ if (haveGlock) \ AFS_GUNLOCK(); \ CODE = uiomove((SRC),(LEN),(RW),(UIO)); \ if (haveGlock) \ AFS_GLOCK(); \ } while(0) #endif #else /* AFS_GLOBAL_SUNLOCK */ #define AFS_COPYIN(SRC,DST,LEN,CODE) \ do { \ CODE = copyin((SRC),(DST),(LEN)); \ } while(0) #define AFS_COPYINSTR(SRC,DST,LEN,CNT,CODE) \ do { \ CODE = copyinstr((SRC),(DST),(LEN),(CNT)); \ } while(0) #define AFS_COPYOUT(SRC,DST,LEN,CODE) \ do { \ CODE = copyout((SRC),(DST),(LEN)); \ } while(0) #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ do { \ (UIO)->uio_rw = (RW); \ CODE = uiomove((SRC),(LEN),(UIO)); \ } while(0) #else /* AFS_OSF_ENV || AFS_FBSD_ENV */ #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ do { \ CODE = uiomove((SRC),(LEN),(RW),(UIO)); \ } while(0) #endif /* AFS_OSF_ENV || AFS_FBSD_ENV */ #endif /* AFS_GLOBAL_SUNLOCK */ /* * encapsulation of kernel data structure accesses */ #define setuerror(erval) u.u_error = (erval) #define getuerror() u.u_error /* Macros for vcache/vnode and vfs arguments to vnode and vfs ops. * These are required for IRIX 6.4 and later, which pass behavior pointers. * Note that the _CONVERT routines get the ";" here so that argument lists * can have arguments after the OSI_x_CONVERT macro is called. */ #define OSI_VN_ARG(V) V #define OSI_VN_DECL(V) struct vnode *V #define OSI_VN_CONVERT(V) #define OSI_VC_ARG(V) V #define OSI_VC_DECL(V) struct vcache *V #define OSI_VC_CONVERT(V) #define OSI_VFS_ARG(V) V #define OSI_VFS_DECL(V) struct vfs *V #define OSI_VFS_CONVERT(V) /* ** Macro for Solaris 2.6 returns 1 if file is larger than 2GB; else returns 0 */ #define AfsLargeFileUio(uio) 0 #define AfsLargeFileSize(pos, off) 0 /* Now include system specific OSI header file. It will redefine macros * defined here as required by the OS. */ #include "osi_machdep.h" /* Declare any structures which use these macros after the OSI implementation * has had the opportunity to redefine them. */ extern struct AFS_UCRED afs_osi_cred; #ifndef osi_curcred #define osi_curcred() (u.u_cred) #endif #endif /* _AFS_OSI_ */