From bb33cbb6eb15664ff56ec5e93d95888878af3d7a Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Thu, 13 Oct 2005 16:12:00 +0000 Subject: [PATCH] macos-rollup-20051013 incorporating STABLE14-macos104-20051005 STABLE14-macos-cleanup-20051006 macos-cleanup-20051006 macos-cleanup-20051007 from the 1.4.x branch, which needed to be forward-ported to work here, sadly. --- acinclude.m4 | 2 +- src/afs/DARWIN/osi_file.c | 116 ++- src/afs/DARWIN/osi_groups.c | 22 +- src/afs/DARWIN/osi_inode.c | 233 ++--- src/afs/DARWIN/osi_machdep.h | 116 ++- src/afs/DARWIN/osi_misc.c | 175 +++- src/afs/DARWIN/osi_module.c | 72 +- src/afs/DARWIN/osi_prototypes.h | 8 + src/afs/DARWIN/osi_sleep.c | 27 +- src/afs/DARWIN/osi_vfsops.c | 320 +++++-- src/afs/DARWIN/osi_vm.c | 22 + src/afs/DARWIN/osi_vnodeops.c | 1212 ++++++++++++++++++------- src/afs/VNOPS/afs_vnop_attrs.c | 62 +- src/afs/VNOPS/afs_vnop_create.c | 14 +- src/afs/VNOPS/afs_vnop_lookup.c | 38 +- src/afs/VNOPS/afs_vnop_read.c | 69 +- src/afs/VNOPS/afs_vnop_readdir.c | 52 +- src/afs/VNOPS/afs_vnop_remove.c | 16 +- src/afs/VNOPS/afs_vnop_strategy.c | 5 +- src/afs/VNOPS/afs_vnop_write.c | 71 +- src/afs/afs.h | 27 +- src/afs/afs_call.c | 44 +- src/afs/afs_callback.c | 22 +- src/afs/afs_cbqueue.c | 16 +- src/afs/afs_daemons.c | 24 +- src/afs/afs_dcache.c | 2 +- src/afs/afs_init.c | 7 + src/afs/afs_memcache.c | 22 +- src/afs/afs_osi.c | 43 +- src/afs/afs_osi.h | 63 +- src/afs/afs_osi_pag.c | 6 + src/afs/afs_osi_uio.c | 6 + src/afs/afs_osi_vget.c | 2 +- src/afs/afs_osidnlc.c | 3 + src/afs/afs_pioctl.c | 29 +- src/afs/afs_server.c | 57 +- src/afs/afs_util.c | 5 + src/afs/afs_vcache.c | 272 ++++-- src/afs/afs_volume.c | 19 + src/afs/lock.h | 4 + src/afs/sysincludes.h | 8 +- src/afsd/afsd.c | 27 +- src/config/afs_args.h | 15 + src/config/param.ppc_darwin_80.h | 9 +- src/dir/dir.c | 2 +- src/libafs/MakefileProto.DARWIN.in | 21 +- src/libafs/afs.ppc_darwin_80.plist.in | 6 +- src/packaging/MacOS/ReadMe.rtf | 6 +- src/packaging/MacOS/buildpkg.sh | 12 +- src/rx/DARWIN/rx_kmutex.c | 28 + src/rx/DARWIN/rx_kmutex.h | 118 ++- src/rx/DARWIN/rx_knet.c | 125 ++- src/rx/UKERNEL/rx_kcommon.h | 2 + src/rx/rx_kcommon.c | 108 ++- src/rx/rx_kcommon.h | 12 + src/rx/rx_kernel.h | 7 + src/rx/rx_packet.c | 4 +- src/rx/rx_prototypes.h | 4 + src/rx/xdr.c | 1 + src/rx/xdr_prototypes.h | 8 +- src/sys/afssyscalls.c | 38 +- src/venus/fstrace.c | 5 + 62 files changed, 3045 insertions(+), 846 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 81421d415..470f49577 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -732,7 +732,7 @@ case $AFS_SYSNAME in DARWIN_PLIST=src/libafs/afs.${AFS_SYSNAME}.plist DARWIN_INFOFILE=afs.${AFS_SYSNAME}.plist dnl the test below fails on darwin, even if the CPPFLAGS below - dnl are added. the headers from Kernel.Framework must be used + dnl are added. the headers from Kernel.framework must be used dnl when KERNEL is defined. dnl really, such a thing isn't guaranteed to work on any diff --git a/src/afs/DARWIN/osi_file.c b/src/afs/DARWIN/osi_file.c index 478541476..9b05020e1 100644 --- a/src/afs/DARWIN/osi_file.c +++ b/src/afs/DARWIN/osi_file.c @@ -32,6 +32,9 @@ afs_InitDualFSCacheOps(struct vnode *vp) { int code; static int inited = 0; +#ifdef AFS_DARWIN80_ENV + char *buffer = (char*)_MALLOC(MFSNAMELEN, M_TEMP, M_WAITOK); +#endif if (inited) return; @@ -39,24 +42,51 @@ afs_InitDualFSCacheOps(struct vnode *vp) if (vp == NULL) return; +#ifdef AFS_DARWIN80_ENV + vfs_name(vnode_mount(vp), buffer); + if (strncmp("hfs", buffer, 3) == 0) +#else if (strncmp("hfs", vp->v_mount->mnt_vfc->vfc_name, 3) == 0) +#endif afs_CacheFSType = AFS_APPL_HFS_CACHE; +#ifdef AFS_DARWIN80_ENV + else if (strncmp("ufs", buffer, 3) == 0) +#else else if (strncmp("ufs", vp->v_mount->mnt_vfc->vfc_name, 3) == 0) +#endif afs_CacheFSType = AFS_APPL_UFS_CACHE; else osi_Panic("Unknown cache vnode type\n"); +#ifdef AFS_DARWIN80_ENV + _FREE(buffer, M_TEMP); +#endif } ino_t +#ifdef AFS_DARWIN80_ENV +VnodeToIno(vnode_t avp) +#else VnodeToIno(vnode_t * avp) +#endif { unsigned long ret; +#ifndef AFS_DARWIN80_ENV if (afs_CacheFSType == AFS_APPL_UFS_CACHE) { struct inode *ip = VTOI(avp); ret = ip->i_number; } else if (afs_CacheFSType == AFS_APPL_HFS_CACHE) { -#ifndef VTOH +#endif +#if defined(AFS_DARWIN80_ENV) + struct vattr va; + VATTR_INIT(&va); + VATTR_WANTED(&va, va_fileid); + if (vnode_getattr(avp, &va, afs_osi_ctxtp)) + osi_Panic("VOP_GETATTR failed in VnodeToIno\n"); + if (!VATTR_ALL_SUPPORTED(&va)) + osi_Panic("VOP_GETATTR unsupported fileid in VnodeToIno\n"); + ret = va.va_fileid; +#elif !defined(VTOH) struct vattr va; if (VOP_GETATTR(avp, &va, &afs_osi_cred, current_proc())) osi_Panic("VOP_GETATTR failed in VnodeToIno\n"); @@ -65,22 +95,37 @@ VnodeToIno(vnode_t * avp) struct hfsnode *hp = VTOH(avp); ret = H_FILEID(hp); #endif +#ifndef AFS_DARWIN80_ENV } else osi_Panic("VnodeToIno called before cacheops initialized\n"); +#endif return ret; } dev_t +#ifdef AFS_DARWIN80_ENV +VnodeToDev(vnode_t avp) +#else VnodeToDev(vnode_t * avp) +#endif { - - +#ifndef AFS_DARWIN80_ENV if (afs_CacheFSType == AFS_APPL_UFS_CACHE) { struct inode *ip = VTOI(avp); return ip->i_dev; } else if (afs_CacheFSType == AFS_APPL_HFS_CACHE) { -#ifndef VTOH /* slow, but works */ +#endif +#if defined(AFS_DARWIN80_ENV) || !defined(VTOH) + struct vattr va; + VATTR_INIT(&va); + VATTR_WANTED(&va, va_fsid); + if (vnode_getattr(avp, &va, afs_osi_ctxtp)) + osi_Panic("VOP_GETATTR failed in VnodeToDev\n"); + if (!VATTR_ALL_SUPPORTED(&va)) + osi_Panic("VOP_GETATTR unsupported fsid in VnodeToIno\n"); + return va.va_fsid; /* XXX they say it's the dev.... */ +#elif !defined(VTOH) struct vattr va; if (VOP_GETATTR(avp, &va, &afs_osi_cred, current_proc())) osi_Panic("VOP_GETATTR failed in VnodeToDev\n"); @@ -89,8 +134,10 @@ VnodeToDev(vnode_t * avp) struct hfsnode *hp = VTOH(avp); return H_DEV(hp); #endif +#ifndef AFS_DARWIN80_ENV } else osi_Panic("VnodeToDev called before cacheops initialized\n"); +#endif } void * @@ -115,14 +162,18 @@ osi_UFSOpen(afs_int32 ainode) } afile = (struct osi_file *)osi_AllocSmallSpace(sizeof(struct osi_file)); AFS_GUNLOCK(); +#ifndef AFS_DARWIN80_ENV if (afs_CacheFSType == AFS_APPL_HFS_CACHE) code = igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev, &ainode, &vp, &va, &dummy); /* XXX hfs is broken */ else if (afs_CacheFSType == AFS_APPL_UFS_CACHE) +#endif code = igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev, (ino_t) ainode, &vp, &va, &dummy); +#ifndef AFS_DARWIN80_ENV else panic("osi_UFSOpen called before cacheops initialized\n"); +#endif AFS_GLOCK(); if (code) { osi_FreeSmallSpace(afile); @@ -144,7 +195,18 @@ afs_osi_Stat(register struct osi_file *afile, register struct osi_stat *astat) AFS_STATCNT(osi_Stat); MObtainWriteLock(&afs_xosi, 320); AFS_GUNLOCK(); +#ifdef AFS_DARWIN80_ENV + VATTR_INIT(&tvattr); + VATTR_WANTED(&tvattr, va_size); + VATTR_WANTED(&tvattr, va_blocksize); + VATTR_WANTED(&tvattr, va_mtime); + VATTR_WANTED(&tvattr, va_atime); + code = vnode_getattr(afile->vnode, &tvattr, afs_osi_ctxtp); + if (code == 0 && !VATTR_ALL_SUPPORTED(&tvattr)) + code = EINVAL; +#else code = VOP_GETATTR(afile->vnode, &tvattr, &afs_osi_cred, current_proc()); +#endif AFS_GLOCK(); if (code == 0) { astat->size = tvattr.va_size; @@ -161,7 +223,11 @@ osi_UFSClose(register struct osi_file *afile) { AFS_STATCNT(osi_Close); if (afile->vnode) { +#ifdef AFS_DARWIN80_ENV + vnode_close(afile->vnode, O_RDWR, afs_osi_ctxtp); +#else AFS_RELE(afile->vnode); +#endif } osi_FreeSmallSpace(afile); @@ -185,20 +251,35 @@ osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize) if (code || tstat.size <= asize) return code; MObtainWriteLock(&afs_xosi, 321); + AFS_GUNLOCK(); +#ifdef AFS_DARWIN80_ENV + VATTR_INIT(&tvattr); + VATTR_SET(&tvattr, va_size, asize); + code = vnode_getattr(afile->vnode, &tvattr, afs_osi_ctxtp); +#else VATTR_NULL(&tvattr); tvattr.va_size = asize; - AFS_GUNLOCK(); code = VOP_SETATTR(afile->vnode, &tvattr, &afs_osi_cred, current_proc()); +#endif AFS_GLOCK(); MReleaseWriteLock(&afs_xosi); return code; } void +#ifdef AFS_DARWIN80_ENV +osi_DisableAtimes(vnode_t avp) +#else osi_DisableAtimes(struct vnode *avp) +#endif { +#ifdef AFS_DARWIN80_ENV + struct vnode_attr vap; - + VATTR_INIT(&vap); + VATTR_CLEAR_SUPPORTED(&vap, va_access_time); + vnode_setattr(avp, &vap, afs_osi_ctxtp); +#else if (afs_CacheFSType == AFS_APPL_UFS_CACHE) { struct inode *ip = VTOI(avp); ip->i_flag &= ~IN_ACCESS; @@ -209,6 +290,7 @@ osi_DisableAtimes(struct vnode *avp) hp->h_nodeflags &= ~IN_ACCESS; } #endif +#endif } @@ -220,6 +302,9 @@ afs_osi_Read(register struct osi_file *afile, int offset, void *aptr, struct AFS_UCRED *oldCred; unsigned int resid; register afs_int32 code; +#ifdef AFS_DARWIN80_ENV + uio_t uio; +#endif AFS_STATCNT(osi_Read); /** @@ -236,9 +321,17 @@ afs_osi_Read(register struct osi_file *afile, int offset, void *aptr, if (offset != -1) afile->offset = offset; AFS_GUNLOCK(); +#ifdef AFS_DARWIN80_ENV + uio=uio_create(1, afile->offset, AFS_UIOSYS, UIO_READ); + uio_addiov(uio, CAST_USER_ADDR_T(aptr), asize); + code = VNOP_READ(afile->vnode, uio, IO_UNIT, afs_osi_ctxtp); + resid = AFS_UIO_RESID(uio); + uio_free(uio); +#else code = gop_rdwr(UIO_READ, afile->vnode, (caddr_t) aptr, asize, afile->offset, AFS_UIOSYS, IO_UNIT, &afs_osi_cred, &resid); +#endif AFS_GLOCK(); if (code == 0) { code = asize - resid; @@ -260,6 +353,9 @@ afs_osi_Write(register struct osi_file *afile, afs_int32 offset, void *aptr, struct AFS_UCRED *oldCred; unsigned int resid; register afs_int32 code; +#ifdef AFS_DARWIN80_ENV + uio_t uio; +#endif AFS_STATCNT(osi_Write); if (!afile) osi_Panic("afs_osi_Write called with null param"); @@ -267,10 +363,18 @@ afs_osi_Write(register struct osi_file *afile, afs_int32 offset, void *aptr, afile->offset = offset; { AFS_GUNLOCK(); +#ifdef AFS_DARWIN80_ENV + uio=uio_create(1, afile->offset, AFS_UIOSYS, UIO_WRITE); + uio_addiov(uio, CAST_USER_ADDR_T(aptr), asize); + code = VNOP_WRITE(afile->vnode, uio, IO_UNIT, afs_osi_ctxtp); + resid = AFS_UIO_RESID(uio); + uio_free(uio); +#else code = gop_rdwr(UIO_WRITE, afile->vnode, (caddr_t) aptr, asize, afile->offset, AFS_UIOSYS, IO_UNIT, &afs_osi_cred, &resid); +#endif AFS_GLOCK(); } if (code == 0) { diff --git a/src/afs/DARWIN/osi_groups.c b/src/afs/DARWIN/osi_groups.c index d5703b51e..7664bdd8e 100644 --- a/src/afs/DARWIN/osi_groups.c +++ b/src/afs/DARWIN/osi_groups.c @@ -20,6 +20,19 @@ RCSID ("$Header$"); +/* We should be doing something better anyway */ +#ifdef AFS_DARWIN80_ENV +int +setpag(proc, cred, pagvalue, newpag, change_parent) + struct proc *proc; + struct ucred **cred; + afs_uint32 pagvalue; + afs_uint32 *newpag; + afs_uint32 change_parent; +{ + return -1; +} +#else #include "afs/sysincludes.h" #include "afsincludes.h" #include "afs/afs_stats.h" /* statistics */ @@ -75,14 +88,6 @@ Afs_xsetgroups(p, args, retval) } -int -setpag(proc, cred, pagvalue, newpag, change_parent) - struct proc *proc; - struct ucred **cred; - afs_uint32 pagvalue; - afs_uint32 *newpag; - afs_uint32 change_parent; -{ gid_t gidset[NGROUPS]; int ngroups, code; int j; @@ -159,3 +164,4 @@ afs_setgroups(struct proc *proc, struct ucred **cred, int ngroups, crfree(oldcr); return (0); } +#endif diff --git a/src/afs/DARWIN/osi_inode.c b/src/afs/DARWIN/osi_inode.c index f13418d19..ddecc6c1d 100644 --- a/src/afs/DARWIN/osi_inode.c +++ b/src/afs/DARWIN/osi_inode.c @@ -22,9 +22,89 @@ RCSID #include "afsincludes.h" /* Afs-based standard headers */ #include "afs/osi_inode.h" #include "afs/afs_stats.h" /* statistics stuff */ +#ifndef AFS_DARWIN80_ENV #include +#endif extern struct ucred afs_osi_cred; +extern int afs_CacheFSType; +#ifdef AFS_DARWIN80_ENV +getinode(fs, dev, inode, vpp, perror) + mount_t fs; + vnode_t *vpp; + dev_t dev; + ino_t inode; + int *perror; +{ + struct vnode *vp; + int code; + vfs_context_t ctx; + char volfspath[64]; + + *vpp = 0; + *perror = 0; + sprintf(volfspath, "/.vol/%d/%d", dev, inode); + code = vnode_open(volfspath, O_RDWR, 0, 0, &vp, afs_osi_ctxtp); + if (code) { + *perror = BAD_IGET; + return code; + } else { + *vpp = vp; + return (0); + } +} + + +igetinode(vfsp, dev, inode, vpp, va, perror) + vnode_t *vpp; + mount_t vfsp; + dev_t dev; + ino_t inode; + struct vattr *va; + int *perror; +{ + vnode_t pvp, vp; + extern struct osi_dev cacheDev; + register int code = 0; + + *perror = 0; + + AFS_STATCNT(igetinode); + if ((code = getinode(vfsp, dev, inode, &vp, perror)) != 0) { + return (code); + } + if (vnode_vtype(vp) != VREG && vnode_vtype(vp) != VDIR && vnode_vtype(vp) != VLNK) { + vnode_close(vp, O_RDWR, afs_osi_ctxtp); + printf("igetinode: bad type %d\n", vnode_vtype(vp)); + return (ENOENT); + } + VATTR_INIT(va); + VATTR_WANTED(va, va_mode); + VATTR_WANTED(va, va_nlink); + VATTR_WANTED(va, va_size); + code = vnode_getattr(vp, va, afs_osi_ctxtp); + if (code) { + vnode_close(vp, O_RDWR, afs_osi_ctxtp); + return code; + } + if (!VATTR_ALL_SUPPORTED(va)) { + vnode_close(vp, O_RDWR, afs_osi_ctxtp); + return ENOENT; + } + if (va->va_mode == 0) { + vnode_close(vp, O_RDWR, afs_osi_ctxtp); + /* Not an allocated inode */ + return (ENOENT); + } + if (va->va_nlink == 0) { + vnode_close(vp, O_RDWR, afs_osi_ctxtp); + return (ENOENT); + } + + *vpp = vp; + return (0); +} +#else getinode(fs, dev, inode, vpp, perror) struct mount *fs; struct vnode **vpp; @@ -85,7 +165,7 @@ getinode(fs, dev, inode, vpp, perror) return (0); } } -extern int afs_CacheFSType; + igetinode(vfsp, dev, inode, vpp, va, perror) struct vnode **vpp; struct mount *vfsp; @@ -151,156 +231,8 @@ iforget(vp) vput(vp); } } +#endif -#if 0 -/* - * icreate system call -- create an inode - */ -afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval) - long *retval; - long dev, near_inode, param1, param2, param3, param4; -{ - int dummy, err = 0; - struct inode *ip, *newip; - register int code; - struct vnode *vp; - - AFS_STATCNT(afs_syscall_icreate); - - if (!afs_suser(NULL)) - return (EPERM); - - code = getinode(0, (dev_t) dev, 2, &ip, &dummy); - if (code) { - return (ENOENT); - } - code = ialloc(ip, (ino_t) near_inode, 0, &newip); - iput(ip); - if (code) { - return (code); - } - IN_LOCK(newip); - newip->i_flag |= IACC | IUPD | ICHG; - - newip->i_nlink = 1; - - newip->i_mode = IFREG; - - IN_UNLOCK(newip); - vp = ITOV(newip); - VN_LOCK(vp); - vp->v_type = VREG; - VN_UNLOCK(vp); - - if (!vp->v_object) { - extern struct vfs_ubcops ufs_ubcops; - extern struct vm_ubc_object *ubc_object_allocate(); - struct vm_ubc_object *vop; - vop = ubc_object_allocate(&vp, &ufs_ubcops, vp->v_mount->m_funnel); - VN_LOCK(vp); - vp->v_object = vop; - VN_UNLOCK(vp); - } - - - IN_LOCK(newip); - newip->i_flags |= IC_XUID | IC_XGID; - newip->i_flags &= ~IC_PROPLIST; - newip->i_vicep1 = param1; - if (param2 == 0x1fffffff /*INODESPECIAL*/) { - newip->i_vicep2 = ((0x1fffffff << 3) + (param4 & 0x3)); - newip->i_vicep3a = (u_short) (param3 >> 16); - newip->i_vicep3b = (u_short) param3; - } else { - newip->i_vicep2 = - (((param2 >> 16) & 0x1f) << 27) + - (((param4 >> 16) & 0x1f) << 22) + (param3 & 0x3fffff); - newip->i_vicep3a = (u_short) param4; - newip->i_vicep3b = (u_short) param2; - } - newip->i_vicemagic = VICEMAGIC; - - *retval = newip->i_number; - IN_UNLOCK(newip); - iput(newip); - return (code); -} - - -afs_syscall_iopen(dev, inode, usrmod, retval) - long *retval; - int dev, inode, usrmod; -{ - struct file *fp; - struct inode *ip; - struct vnode *vp = NULL; - int dummy; - int fd; - extern struct fileops vnops; - register int code; - - AFS_STATCNT(afs_syscall_iopen); - - if (!afs_suser(NULL)) - return (EPERM); - - code = igetinode(0, (dev_t) dev, (ino_t) inode, &ip, &dummy); - if (code) { - return (code); - } - if ((code = falloc(&fp, &fd)) != 0) { - iput(ip); - return (code); - } - IN_UNLOCK(ip); - - FP_LOCK(fp); - fp->f_flag = (usrmod - FOPEN) & FMASK; - fp->f_type = DTYPE_VNODE; - fp->f_ops = &vnops; - fp->f_data = (caddr_t) ITOV(ip); - - FP_UNLOCK(fp); - U_FD_SET(fd, fp, &u.u_file_state); - *retval = fd; - return (0); -} - - -/* - * Support for iinc() and idec() system calls--increment or decrement - * count on inode. - * Restricted to super user. - * Only VICEMAGIC type inodes. - */ -afs_syscall_iincdec(dev, inode, inode_p1, amount) - int dev, inode, inode_p1, amount; -{ - int dummy; - struct inode *ip; - register int code; - - if (!afs_suser(NULL)) - return (EPERM); - - code = igetinode(0, (dev_t) dev, (ino_t) inode, &ip, &dummy); - if (code) { - return (code); - } - if (!IS_VICEMAGIC(ip)) { - return (EPERM); - } else if (ip->i_vicep1 != inode_p1) { - return (ENXIO); - } - ip->i_nlink += amount; - if (ip->i_nlink == 0) { - CLEAR_VICEMAGIC(ip); - } - ip->i_flag |= ICHG; - iput(ip); - return (0); -} -#else afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval) long *retval; long dev, near_inode, param1, param2, param3, param4; @@ -320,4 +252,3 @@ afs_syscall_iincdec(dev, inode, inode_p1, amount) { return EOPNOTSUPP; } -#endif diff --git a/src/afs/DARWIN/osi_machdep.h b/src/afs/DARWIN/osi_machdep.h index 409d64d85..0026eff0f 100644 --- a/src/afs/DARWIN/osi_machdep.h +++ b/src/afs/DARWIN/osi_machdep.h @@ -25,12 +25,36 @@ typedef unsigned short etap_event_t; #endif #endif +#ifdef AFS_DARWIN80_ENV +#include +#include +#include +#else #include -#include #include +#include +#endif +#include +#ifdef AFS_DARWIN80_ENV +#define vop_proc vfs_context_proc(ap->a_context) +#define vop_cred vfs_context_ucred(ap->a_context) +#define cn_proc(cnp) vfs_context_proc(ap->a_context) +#define cn_cred(cnp) vfs_context_ucred(ap->a_context) +#define vop_cn_proc vfs_context_proc(ap->a_context) +#define vop_cn_cred vfs_context_ucred(ap->a_context) +#define getpid() proc_selfpid() +#define getppid() proc_selfppid() +#else +#define vop_proc ap->a_p +#define vop_cred ap->a_cred +#define cn_proc(cnp) (cnp)->cn_proc +#define cn_cred(cnp) (cnp)->cn_cred +#define vop_cn_proc cn_proc(ap->a_cnp) +#define vop_cn_cred cn_cred(ap->a_cnp) #define getpid() current_proc()->p_pid #define getppid() current_proc()->p_pptr->p_pid +#endif #undef gop_lookupname #define gop_lookupname osi_lookupname @@ -39,14 +63,70 @@ typedef unsigned short etap_event_t; /* vcexcl - used only by afs_create */ enum vcexcl { EXCL, NONEXCL }; +#ifndef AFS_DARWIN80_ENV +#define vnode_clearfsnode(x) ((x)->v_data = 0) +#define vnode_fsnode(x) (x)->v_data +#define vnode_lock(x) vn_lock(x, LK_EXCLUSIVE | LK_RETRY, current_proc()); +#define vnode_isvroot(x) (((x)->v_flag & VROOT)?1:0) +#define vnode_vtype(x) (x)->v_type +#define vnode_isdir(x) ((x)->v_type == VDIR) + +#define vfs_flags(x) (x)->v_flags +#define vfs_setflags(x, y) (x)->mnt_flag |= (y) +#define vfs_clearflags(x, y) (x)->mnt_flag &= (~(y)) +#define vfs_isupdate(x) ((x)->mnt_flag & MNT_UPDATE) +#define vfs_fsprivate(x) (x)->mnt_data +#define vfs_setfsprivate(x,y) (x)->mnt_data = (y) +#define vfs_typenum(x) (x)->mnt_vfc->vfc_typenum +#endif + +#ifdef AFS_DARWIN80_ENV +#define vrele vnode_rele +#define vput vnode_rele +#define vref vnode_ref +#define vattr vnode_attr +#if 0 +#define vn_lock(v, unused1, unused2) vnode_get((v)) +#define VOP_LOCK(v, unused1, unused2) vnode_get((v)) +#define VOP_UNLOCK(v, unused1, unused2) vnode_put((v)) +#endif + +#define va_size va_data_size +#define va_atime va_access_time +#define va_mtime va_modify_time +#define va_ctime va_change_time +#define va_bytes va_total_alloc +#define va_blocksize va_iosize +#define va_nodeid va_fileid + +#define crref kauth_cred_get_with_ref +#define crhold kauth_cred_ref +#define crfree kauth_cred_rele +#define crdup kauth_cred_dup + +extern vfs_context_t afs_osi_ctxtp; +extern int afs_osi_ctxtp_initialized; +#endif + /* * Time related macros */ #ifndef AFS_DARWIN60_ENV extern struct timeval time; #endif +#ifdef AFS_DARWIN80_ENV +static inline time_t osi_Time(void) { + struct timeval _now; + microtime(&_now); + return _now.tv_sec; +} +#else #define osi_Time() (time.tv_sec) +#endif #define afs_hz hz +#ifdef AFS_DARWIN80_ENV +extern int hz; +#endif #define PAGESIZE 8192 @@ -58,6 +138,10 @@ extern struct timeval time; #define VN_HOLD(vp) darwin_vn_hold(vp) #define VN_RELE(vp) vrele(vp); +void darwin_vn_hold(struct vnode *vp); +#ifdef AFS_DARWIN80_ENV +void darwin_vn_rele(struct vnode *vp); +#endif #define gop_rdwr(rw,gp,base,len,offset,segflg,unit,cred,aresid) \ vn_rdwr((rw),(gp),(base),(len),(offset),(segflg),(unit),(cred),(aresid),current_proc()) @@ -67,6 +151,23 @@ extern struct timeval time; #ifdef KERNEL extern thread_t afs_global_owner; /* simple locks cannot be used since sleep can happen at any time */ +#ifdef AFS_DARWIN80_ENV +/* mach locks still don't have an exported try, but we are forced to use them */ +extern lck_mtx_t *afs_global_lock; +#define AFS_GLOCK() \ + do { \ + osi_Assert(afs_global_owner != current_thread()); \ + lck_mtx_lock(afs_global_lock); \ + osi_Assert(afs_global_owner == 0); \ + afs_global_owner = current_thread(); \ + } while (0) +#define AFS_GUNLOCK() \ + do { \ + osi_Assert(afs_global_owner == current_thread()); \ + afs_global_owner = 0; \ + lck_mtx_unlock(afs_global_lock); \ + } while(0) +#else /* Should probably use mach locks rather than bsd locks, since we use the mach thread control api's elsewhere (mach locks not used for consistency with rx, since rx needs lock_write_try() in order to use mach locks @@ -84,6 +185,7 @@ extern struct lock__bsd__ afs_global_lock; afs_global_owner = 0; \ lockmgr(&afs_global_lock, LK_RELEASE, 0, current_proc()); \ } while(0) +#endif #define ISAFS_GLOCK() (afs_global_owner == current_thread()) #define SPLVAR @@ -101,14 +203,22 @@ extern struct lock__bsd__ afs_global_lock; #define AFS_APPL_UFS_CACHE 1 #define AFS_APPL_HFS_CACHE 2 -extern ino_t VnodeToIno(vnode_t * vp); -extern dev_t VnodeToDev(vnode_t * vp); +extern ino_t VnodeToIno(struct vnode * vp); +extern dev_t VnodeToDev(struct vnode * vp); +extern int igetinode(mount_t vfsp, dev_t dev , ino_t inode, vnode_t *vpp, + struct vattr *va, int *perror); #define osi_curproc() current_proc() /* FIXME */ #define osi_curcred() &afs_osi_cred +#ifdef AFS_DARWIN80_ENV +uio_t afsio_darwin_partialcopy(uio_t auio, int size); + +#define uprintf printf +#endif + #endif /* KERNEL */ #endif /* _OSI_MACHDEP_H_ */ diff --git a/src/afs/DARWIN/osi_misc.c b/src/afs/DARWIN/osi_misc.c index 701b09106..d65500af9 100644 --- a/src/afs/DARWIN/osi_misc.c +++ b/src/afs/DARWIN/osi_misc.c @@ -17,6 +17,38 @@ RCSID #include "afsincludes.h" #include +#ifndef PATHBUFLEN +#define PATHBUFLEN 256 +#endif + +#ifdef AFS_DARWIN80_ENV +int +osi_lookupname(char *aname, enum uio_seg seg, int followlink, + struct vnode **vpp) { + vfs_context_t ctx; + char tname[PATHBUFLEN]; + int code, flags; + size_t len; + + if (seg == AFS_UIOUSER) { /* XXX 64bit */ + AFS_COPYINSTR(aname, tname, sizeof(tname), &len, code); + if (code) + return code; + aname=tname; + } + flags = 0; + if (!followlink) + flags |= VNODE_LOOKUP_NOFOLLOW; + ctx=vfs_context_create(NULL); + code = vnode_lookup(aname, flags, vpp, ctx); + if (!code) { /* get a usecount */ + vnode_ref(*vpp); + vnode_put(*vpp); + } + vfs_context_rele(ctx); + return code; +} +#else int osi_lookupname(char *aname, enum uio_seg seg, int followlink, struct vnode **vpp) @@ -37,20 +69,161 @@ osi_lookupname(char *aname, enum uio_seg seg, int followlink, VOP_UNLOCK(n.ni_vp, 0, current_proc()); return 0; } +#endif /* * afs_suser() returns true if the caller is superuser, false otherwise. * * Note that it must NOT set errno. */ - +int afs_suser(void *credp) { int error; struct proc *p = current_proc(); +#ifdef AFS_DARWIN80_ENV + if ((error = proc_suser(p)) == 0) { + return (1); + } + return (0); +#else if ((error = suser(p->p_ucred, &p->p_acflag)) == 0) { return (1); } return (0); +#endif +} + +#ifdef AFS_DARWIN80_ENV +uio_t afsio_darwin_partialcopy(uio_t auio, int size) { + uio_t res; + int i; + user_addr_t iovaddr; + user_size_t iovsize; + + /* XXX 64 bit userspaace? */ + res = uio_create(uio_iovcnt(auio), uio_offset(auio), + uio_isuserspace(auio) ? UIO_USERSPACE32 : UIO_SYSSPACE32, + uio_rw(auio)); + + for (i = 0;i < uio_iovcnt(auio) && size > 0;i++) { + if (uio_getiov(auio, i, &iovaddr, &iovsize)) + break; + if (iovsize > size) + iovsize = size; + if (uio_addiov(res, iovaddr, iovsize)) + break; + size -= iovsize; + } + return res; } + +vfs_context_t afs_osi_ctxtp; +int afs_osi_ctxtp_initialized; +static thread_t vfs_context_owner; +#define RECURSIVE_VFS_CONTEXT 1 +#if RECURSIVE_VFS_CONTEXT +static proc_t vfs_context_curproc; +int vfs_context_ref; +#else +#define vfs_context_ref 1 +#endif +void get_vfs_context(void) { + int isglock = ISAFS_GLOCK(); + + if (!isglock) + AFS_GLOCK(); + if (afs_osi_ctxtp_initialized) { + if (!isglock) + AFS_GUNLOCK(); + return; + } + osi_Assert(vfs_context_owner != current_thread()); +#if RECURSIVE_VFS_CONTEXT + if (afs_osi_ctxtp && current_proc() == vfs_context_curproc) { + vfs_context_ref++; + vfs_context_owner = current_thread(); + if (!isglock) + AFS_GUNLOCK(); + return; + } +#endif + while (afs_osi_ctxtp && vfs_context_ref) { + printf("[%d] waiting for afs_osi_ctxtp\n", proc_selfpid()); + afs_osi_Sleep(&afs_osi_ctxtp); + if (afs_osi_ctxtp_initialized) { + printf("[%d] ok\n", proc_selfpid()); + if (!isglock) + AFS_GUNLOCK(); + return; + } + if (!afs_osi_ctxtp || !vfs_context_ref) + printf("[%d] ok\n", proc_selfpid()); + } +#if RECURSIVE_VFS_CONTEXT + vfs_context_rele(afs_osi_ctxtp); + vfs_context_ref=1; +#else + osi_Assert(vfs_context_owner == (thread_t)0); +#endif + afs_osi_ctxtp = vfs_context_create(NULL); + vfs_context_owner = current_thread(); + vfs_context_curproc = current_proc(); + if (!isglock) + AFS_GUNLOCK(); +} + +void put_vfs_context(void) { + int isglock = ISAFS_GLOCK(); + + if (!isglock) + AFS_GLOCK(); + if (afs_osi_ctxtp_initialized) { + if (!isglock) + AFS_GUNLOCK(); + return; + } +#if RECURSIVE_VFS_CONTEXT + if (vfs_context_owner == current_thread()) + vfs_context_owner = (thread_t)0; + vfs_context_ref--; +#else + osi_Assert(vfs_context_owner == current_thread()); + vfs_context_rele(afs_osi_ctxtp); + afs_osi_ctxtp = NULL; + vfs_context_owner = (thread_t)0; +#endif + afs_osi_Wakeup(&afs_osi_ctxtp); + if (!isglock) + AFS_GUNLOCK(); +} + +extern int afs3_syscall(); + +int afs_cdev_nop_openclose(dev_t dev, int flags, int devtype,struct proc *p) { + return 0; +} +extern int afs3_syscall(struct proc *p, void *data, unsigned long *retval); + +int +afs_cdev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) { + unsigned long retval=0; + int code; + struct afssysargs *a = (struct afssysargs *)data; + if (proc_is64bit(p)) + return EINVAL; + + if (cmd != VIOC_SYSCALL) { + return EINVAL; + } + + code=afs3_syscall(p, data, &retval); + if (code) + return code; + if (retval && a->syscall != AFSCALL_CALL && a->param1 != AFSOP_CACHEINODE) { printf("SSCall(%d,%d) is returning non-error value %d\n", a->syscall, a->param1, retval); } + a->retval = retval; + return 0; +} + +#endif diff --git a/src/afs/DARWIN/osi_module.c b/src/afs/DARWIN/osi_module.c index d4e1136ef..5c1720a61 100644 --- a/src/afs/DARWIN/osi_module.c +++ b/src/afs/DARWIN/osi_module.c @@ -6,14 +6,34 @@ RCSID #include "afs/sysincludes.h" #include "afsincludes.h" +#ifdef AFS_DARWIN80_ENV +static vfstable_t afs_vfstable; +static struct vfs_fsentry afs_vfsentry; +extern struct vnodeopv_desc afs_vnodeop_opv_desc; +extern struct vnodeopv_desc afs_dead_vnodeop_opv_desc; +static struct vnodeopv_desc *afs_vnodeop_opv_desc_list[2] = + { &afs_vnodeop_opv_desc, &afs_dead_vnodeop_opv_desc }; + + +#include +#include +#define seltrue eno_select +struct cdevsw afs_cdev = NO_CDEVICE; +#undef seltrue +static int afs_cdev_major; +extern open_close_fcn_t afs_cdev_nop_openclose; +extern ioctl_fcn_t afs_cdev_ioctl; +static void *afs_cdev_devfs_handle; +#else #ifdef AFS_DARWIN60_ENV /* not in Kernel.framework anymore !?! */ #include #else #include "sys/syscall.h" #endif +struct vfsconf afs_vfsconf; +#endif #include -struct vfsconf afs_vfsconf; extern struct vfsops afs_vfsops; extern struct mount *afs_globalVFS; extern int Afs_xsetgroups(); @@ -26,10 +46,32 @@ extern int maxvfsconf; kern_return_t afs_modload(struct kmod_info *ki, void *data) { - if (sysent[AFS_SYSCALL].sy_call != nosys) { - printf("AFS_SYSCALL in use. aborting\n"); + osi_Init(); +#ifdef AFS_DARWIN80_ENV + memset(&afs_vfsentry, 0, sizeof(struct vfs_fsentry)); + strcpy(afs_vfsentry.vfe_fsname, "afs"); + afs_vfsentry.vfe_vfsops = &afs_vfsops; + afs_vfsentry.vfe_vopcnt = 2; + afs_vfsentry.vfe_opvdescs = afs_vnodeop_opv_desc_list; + /* We may be 64bit ready too (VFS_TBL64BITREADY) */ + afs_vfsentry.vfe_flags = VFS_TBLTHREADSAFE|VFS_TBLNOTYPENUM; + if (vfs_fsadd(&afs_vfsentry, &afs_vfstable)) { + printf("AFS: vfs_fsadd failed. aborting\n"); return KERN_FAILURE; } + afs_cdev.d_open = &afs_cdev_nop_openclose; + afs_cdev.d_close = &afs_cdev_nop_openclose; + afs_cdev.d_ioctl = &afs_cdev_ioctl; + afs_cdev_major = cdevsw_add(-1, &afs_cdev); + if (afs_cdev_major == -1) { + printf("AFS: cdevsw_add failed. aborting\n"); + vfs_fsremove(afs_vfstable); + return KERN_FAILURE; + } + afs_cdev_devfs_handle = devfs_make_node(makedev(afs_cdev_major, 0), + DEVFS_CHAR, UID_ROOT, GID_WHEEL, + 0666, "openafs_ioctl", 0); +#else memset(&afs_vfsconf, 0, sizeof(struct vfsconf)); strcpy(afs_vfsconf.vfc_name, "afs"); afs_vfsconf.vfc_vfsops = &afs_vfsops; @@ -39,6 +81,10 @@ afs_modload(struct kmod_info *ki, void *data) printf("AFS: vfsconf_add failed. aborting\n"); return KERN_FAILURE; } + if (sysent[AFS_SYSCALL].sy_call != nosys) { + printf("AFS_SYSCALL in use. aborting\n"); + return KERN_FAILURE; + } sysent[SYS_setgroups].sy_call = Afs_xsetgroups; #if 0 sysent[SYS_ioctl].sy_call = afs_xioctl; @@ -48,6 +94,11 @@ afs_modload(struct kmod_info *ki, void *data) sysent[AFS_SYSCALL].sy_parallel = 0; #ifdef KERNEL_FUNNEL sysent[AFS_SYSCALL].sy_funnel = KERNEL_FUNNEL; +#endif +#endif +#ifdef AFS_DARWIN80_ENV + MUTEX_SETUP(); + afs_global_lock = lck_mtx_alloc_init(openafs_lck_grp, 0); #endif return KERN_SUCCESS; } @@ -57,18 +108,31 @@ afs_modunload(struct kmod_info * ki, void *data) { if (afs_globalVFS) return KERN_FAILURE; +#ifdef AFS_DARWIN80_ENV + if (vfs_fsremove(afs_vfstable)) + return KERN_FAILURE; + devfs_remove(afs_cdev_devfs_handle); + cdevsw_remove(afs_cdev_major, &afs_cdev); +#else if (vfsconf_del("afs")) return KERN_FAILURE; /* give up syscall entries for ioctl & setgroups, which we've stolen */ #if 0 sysent[SYS_ioctl].sy_call = ioctl; #endif +#ifndef AFS_DARWIN80_ENV sysent[SYS_setgroups].sy_call = setgroups; +#endif /* give up the stolen syscall entry */ sysent[AFS_SYSCALL].sy_narg = 0; sysent[AFS_SYSCALL].sy_call = nosys; +#endif +#ifdef AFS_DARWIN80_ENV + MUTEX_FINISH(); + lck_mtx_free(afs_global_lock, openafs_lck_grp); +#endif return KERN_SUCCESS; } -KMOD_EXPLICIT_DECL(org.openafs.filesystems.afs, VERSION, afs_modload, +KMOD_EXPLICIT_DECL(org.openafs.filesystems.afs, "1.3.82", afs_modload, afs_modunload) diff --git a/src/afs/DARWIN/osi_prototypes.h b/src/afs/DARWIN/osi_prototypes.h index c97588bba..a5a5ccdd7 100644 --- a/src/afs/DARWIN/osi_prototypes.h +++ b/src/afs/DARWIN/osi_prototypes.h @@ -20,6 +20,9 @@ extern afs_rwlock_t afs_xosi; /* osi_misc.c */ extern int osi_lookupname(char *aname, enum uio_seg seg, int followlink, struct vnode **vpp); +extern int afs_suser(void *credp); +extern void get_vfs_context(void); +extern void put_vfs_context(void); /* osi_sleep.c */ extern void afs_osi_fullSigMask(void); @@ -28,4 +31,9 @@ extern void afs_osi_fullSigRestore(void); /* osi_vm.c */ extern void osi_VM_NukePages(struct vnode *vp, off_t offset, off_t size); extern int osi_VM_Setup(struct vcache *avc, int force); + +/* osi_vnodeops.c */ +extern int afs_darwin_getnewvnode(struct vcache *avc); +extern int afs_darwin_finalizevnode(struct vcache *avc, struct vnode *parent, + struct componentname *cnp, int isroot); #endif /* _OSI_PROTO_H_ */ diff --git a/src/afs/DARWIN/osi_sleep.c b/src/afs/DARWIN/osi_sleep.c index 98338aaaf..193e3a1d4 100644 --- a/src/afs/DARWIN/osi_sleep.c +++ b/src/afs/DARWIN/osi_sleep.c @@ -138,12 +138,16 @@ afs_osi_Sleep(void *event) while (seq == evp->seq) { AFS_ASSERT_GLOCK(); AFS_GUNLOCK(); +#ifdef AFS_DARWIN80_ENV + msleep(event, NULL, PVFS, "afs_osi_Sleep", NULL); +#else #ifdef AFS_DARWIN14_ENV /* this is probably safe for all versions, but testing is hard */ sleep(event, PVFS); #else assert_wait((event_t) event, 0); thread_block(0); +#endif #endif AFS_GLOCK(); } @@ -153,6 +157,7 @@ afs_osi_Sleep(void *event) void afs_osi_fullSigMask() { +#ifndef AFS_DARWIN80_ENV struct uthread *user_thread = (struct uthread *)get_bsdthread_info(current_act()); /* Protect original sigmask */ @@ -162,11 +167,13 @@ afs_osi_fullSigMask() /* Mask all signals */ user_thread->uu_sigmask = ~(sigset_t)0; } +#endif } void afs_osi_fullSigRestore() { +#ifndef AFS_DARWIN80_ENV struct uthread *user_thread = (struct uthread *)get_bsdthread_info(current_act()); /* Protect original sigmask */ @@ -176,6 +183,7 @@ afs_osi_fullSigRestore() /* Clear the oldmask */ user_thread->uu_oldmask = (sigset_t)0; } +#endif } int @@ -199,15 +207,29 @@ osi_TimedSleep(char *event, afs_int32 ams, int aintok) { int code = 0; struct afs_event *evp; - int ticks, seq; + int seq; int prio; +#ifdef AFS_DARWIN80_ENV + struct timespec ts; +#else + int ticks; +#endif - ticks = (ams * afs_hz) / 1000; evp = afs_getevent(event); seq = evp->seq; AFS_GUNLOCK(); +#ifdef AFS_DARWIN80_ENV + if (aintok) + prio = PCATCH | PPAUSE; + else + prio = PVFS; + ts.tv_sec = ams / 1000; + ts.tv_nsec = (ams % 1000) * 1000000; + code = msleep(event, NULL, prio, "afs_osi_TimedSleep", &ts); +#else + ticks = (ams * afs_hz) / 1000; #ifdef AFS_DARWIN14_ENV /* this is probably safe for all versions, but testing is hard. */ /* using tsleep instead of assert_wait/thread_set_timer/thread_block @@ -227,6 +249,7 @@ osi_TimedSleep(char *event, afs_int32 ams, int aintok) thread_set_timer(ticks, NSEC_PER_SEC / hz); thread_block(0); code = 0; +#endif #endif AFS_GLOCK(); if (seq == evp->seq) diff --git a/src/afs/DARWIN/osi_vfsops.c b/src/afs/DARWIN/osi_vfsops.c index 64d085eda..ed34e60af 100644 --- a/src/afs/DARWIN/osi_vfsops.c +++ b/src/afs/DARWIN/osi_vfsops.c @@ -13,12 +13,19 @@ RCSID #include #include #include +#ifndef AFS_DARWIN80_ENV #include +#endif #include #include "../afs/sysctl.h" +#ifndef M_UFSMNT +#define M_UFSMNT M_TEMP /* DARWIN80 MALLOC doesn't look at the type anyway */ +#endif + struct vcache *afs_globalVp = 0; struct mount *afs_globalVFS = 0; +int afs_vfs_typenum; int afs_quotactl() @@ -45,63 +52,102 @@ afs_vptofh(vp, fhp) return (EINVAL); } +#ifdef AFS_DARWIN80_ENV +#define CTX_TYPE vfs_context_t +#define CTX_PROC_CONVERT(C) vfs_context_proc((C)) +#define STATFS_TYPE struct vfsstatfs +#else +#define CTX_TYPE struct proc * +#define CTX_PROC_CONVERT(C) (C) +#define STATFS_TYPE struct statfs +#define vfs_statfs(VFS) &(VFS)->mnt_stat +#endif +#define PROC_DECL(out,in) struct proc *out = CTX_PROC_CONVERT(in) + int afs_start(mp, flags, p) struct mount *mp; int flags; - struct proc *p; + CTX_TYPE p; { return (0); /* nothing to do. ? */ } +int +afs_statfs(struct mount *mp, STATFS_TYPE *abp, CTX_TYPE ctx); +#ifdef AFS_DARWIN80_ENV +int +afs_mount(mp, devvp, data, ctx) + register struct mount *mp; + vnode_t *devvp; + user_addr_t data; + vfs_context_t ctx; +#else int afs_mount(mp, path, data, ndp, p) register struct mount *mp; char *path; caddr_t data; struct nameidata *ndp; - struct proc *p; + CTX_TYPE ctx; +#endif { /* ndp contains the mounted-from device. Just ignore it. * we also don't care about our proc struct. */ size_t size; int error; +#ifdef AFS_DARWIN80_ENV + struct vfsioattr ioattr; + /* vfs_statfs advertised as RO, but isn't */ + /* new api will be needed to initialize this information (nfs needs to + set mntfromname too) */ +#endif + STATFS_TYPE *mnt_stat = vfs_statfs(mp); - if (mp->mnt_flag & MNT_UPDATE) + if (vfs_isupdate(mp)) return EINVAL; AFS_GLOCK(); AFS_STATCNT(afs_mount); - if (data == NULL && afs_globalVFS) { /* Don't allow remounts. */ + if (data == 0 && afs_globalVFS) { /* Don't allow remounts. */ AFS_GUNLOCK(); return (EBUSY); } afs_globalVFS = mp; +#ifdef AFS_DARWIN80_ENV + vfs_ioattr(mp, &ioattr); + ioattr.io_devblocksize = 8192; + vfs_setioattr(mp, &ioattr); + /* f_iosize is handled in VFS_GETATTR */ +#else mp->vfs_bsize = 8192; - vfs_getnewfsid(mp); mp->mnt_stat.f_iosize = 8192; +#endif + vfs_getnewfsid(mp); +#ifndef AFS_DARWIN80_ENV (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size); - memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN); +#endif + memset(mnt_stat->f_mntfromname, 0, MNAMELEN); - if (data == NULL) { - strcpy(mp->mnt_stat.f_mntfromname, "AFS"); + if (data == 0) { + strcpy(mnt_stat->f_mntfromname, "AFS"); /* null terminated string "AFS" will fit, just leave it be. */ - mp->mnt_data = (qaddr_t) NULL; + vfs_setfsprivate(mp, NULL); } else { struct VenusFid *rootFid = NULL; struct volume *tvp; char volName[MNAMELEN]; - (void)copyinstr((char *)data, volName, MNAMELEN - 1, &size); + (void)copyinstr(data, volName, MNAMELEN - 1, &size); memset(volName + size, 0, MNAMELEN - size); if (volName[0] == 0) { - strcpy(mp->mnt_stat.f_mntfromname, "AFS"); - mp->mnt_data = (qaddr_t) & afs_rootFid; + strcpy(mnt_stat->f_mntfromname, "AFS"); + vfs_setfsprivate(mp, &afs_rootFid); } else { struct cell *localcell = afs_GetPrimaryCell(READ_LOCK); if (localcell == NULL) { @@ -110,7 +156,7 @@ afs_mount(mp, path, data, ndp, p) } /* Set the volume identifier to "AFS:volume.name" */ - snprintf(mp->mnt_stat.f_mntfromname, MNAMELEN - 1, "AFS:%s", + snprintf(mnt_stat->f_mntfromname, MNAMELEN - 1, "AFS:%s", volName); tvp = afs_GetVolumeByName(volName, localcell->cellNum, 1, @@ -129,35 +175,45 @@ afs_mount(mp, path, data, ndp, p) return ENODEV; } - mp->mnt_data = (qaddr_t) rootFid; + vfs_setfsprivate(mp, &rootFid); } } +#ifdef AFS_DARWIN80_ENV + afs_vfs_typenum=vfs_typenum(mp); + vfs_setauthopaque(mp); + vfs_setauthopaqueaccess(mp); +#else strcpy(mp->mnt_stat.f_fstypename, "afs"); +#endif AFS_GUNLOCK(); - (void)afs_statfs(mp, &mp->mnt_stat, p); + (void)afs_statfs(mp, mnt_stat, ctx); return 0; } int -afs_unmount(mp, flags, p) +afs_unmount(mp, flags, ctx) struct mount *mp; int flags; - struct proc *p; + CTX_TYPE ctx; { - + void *mdata = vfs_fsprivate(mp); AFS_GLOCK(); AFS_STATCNT(afs_unmount); - if (mp->mnt_data != (qaddr_t) - 1) { - if (mp->mnt_data != NULL) { - FREE(mp->mnt_data, M_UFSMNT); - mp->mnt_data = (qaddr_t) - 1; + if (mdata != (qaddr_t) - 1) { + if (mdata != NULL) { + vfs_setfsprivate(mp, (qaddr_t) - 1); + FREE(mdata, M_UFSMNT); } else { if (flags & MNT_FORCE) { if (afs_globalVp) { +#ifdef AFS_DARWIN80_ENV + afs_PutVCache(afs_globalVp); +#else AFS_GUNLOCK(); vrele(AFSTOV(afs_globalVp)); AFS_GLOCK(); +#endif } afs_globalVp = NULL; AFS_GUNLOCK(); @@ -170,7 +226,7 @@ afs_unmount(mp, flags, p) return EBUSY; } } - mp->mnt_flag &= ~MNT_LOCAL; + vfs_clearflags(mp, MNT_LOCAL); } AFS_GUNLOCK(); @@ -178,56 +234,97 @@ afs_unmount(mp, flags, p) return 0; } +#ifdef AFS_DARWIN80_ENV +int +afs_root(struct mount *mp, struct vnode **vpp, vfs_context_t ctx) +#else int afs_root(struct mount *mp, struct vnode **vpp) +#endif { + void *mdata = vfs_fsprivate(mp); int error; struct vrequest treq; register struct vcache *tvp = 0; +#ifdef AFS_DARWIN80_ENV + struct ucred *cr = vfs_context_ucred(ctx); + int needref=0; +#else struct proc *p = current_proc(); - struct ucred cr; + struct ucred _cr; + struct ucred *cr =&_cr; pcred_readlock(p); cr = *p->p_cred->pc_ucred; pcred_unlock(p); +#endif AFS_GLOCK(); AFS_STATCNT(afs_root); - if (mp->mnt_data == NULL && afs_globalVp + if (mdata == NULL && afs_globalVp && (afs_globalVp->states & CStatd)) { tvp = afs_globalVp; error = 0; - } else if (mp->mnt_data == (qaddr_t) - 1) { +#ifdef AFS_DARWIN80_ENV + needref=1; +#endif + } else if (mdata == (qaddr_t) - 1) { error = ENOENT; } else { - struct VenusFid *rootFid = (mp->mnt_data == NULL) - ? &afs_rootFid : (struct VenusFid *)mp->mnt_data; - - if (afs_globalVp) { - afs_PutVCache(afs_globalVp); - afs_globalVp = NULL; - } + struct VenusFid *rootFid = (mdata == NULL) + ? &afs_rootFid : (struct VenusFid *)mdata; - if (!(error = afs_InitReq(&treq, &cr)) && !(error = afs_CheckInit())) { + if (!(error = afs_InitReq(&treq, cr)) && !(error = afs_CheckInit())) { tvp = afs_GetVCache(rootFid, &treq, NULL, NULL); +#ifdef AFS_DARWIN80_ENV + if (tvp) { + AFS_GUNLOCK(); + error = afs_darwin_finalizevnode(tvp, NULL, NULL, 1); + AFS_GLOCK(); + if (error) + tvp = NULL; + else + /* re-acquire the usecount that finalizevnode disposed of */ + vnode_ref(AFSTOV(tvp)); + } +#endif /* we really want this to stay around */ if (tvp) { - if (mp->mnt_data == NULL) + if (mdata == NULL) { + if (afs_globalVp) { + afs_PutVCache(afs_globalVp); + afs_globalVp = NULL; + } afs_globalVp = tvp; +#ifdef AFS_DARWIN80_ENV + needref=1; +#endif + } } else error = ENOENT; } } if (tvp) { +#ifndef AFS_DARWIN80_ENV /* DARWIN80 caller does not need a usecount reference */ osi_vnhold(tvp, 0); AFS_GUNLOCK(); vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, p); AFS_GLOCK(); - if (mp->mnt_data == NULL) { +#endif +#ifdef AFS_DARWIN80_ENV + if (needref) /* this iocount is for the caller. the initial iocount + is for the eventual afs_PutVCache. for mdata != null, + there will not be a PutVCache, so the caller gets the + initial (from GetVCache or finalizevnode) iocount*/ + vnode_get(AFSTOV(tvp)); +#endif + if (mdata == NULL) { afs_globalVFS = mp; } *vpp = AFSTOV(tvp); +#ifndef AFS_DARWIN80_ENV AFSTOV(tvp)->v_flag |= VROOT; AFSTOV(tvp)->v_vfsp = mp; +#endif } afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *vpp, @@ -236,6 +333,7 @@ afs_root(struct mount *mp, struct vnode **vpp) return error; } +#ifndef AFS_DARWIN80_ENV /* vget vfsop never had this prototype AFAIK */ int afs_vget(mp, lfl, vp) struct mount *mp; @@ -254,17 +352,29 @@ afs_vget(mp, lfl, vp) return error; } +int afs_vfs_vget(struct mount *mp, void *ino, struct vnode **vpp) +{ + return ENOENT; /* cannot implement */ +} + +#endif + int -afs_statfs(struct mount *mp, struct statfs *abp, struct proc *p) +afs_statfs(struct mount *mp, STATFS_TYPE *abp, CTX_TYPE ctx) { + STATFS_TYPE *sysstat = vfs_statfs(mp); AFS_GLOCK(); AFS_STATCNT(afs_statfs); #if 0 abp->f_type = MOUNT_AFS; #endif +#ifdef AFS_DARWIN80_ENV + abp->f_bsize = abp->f_iosize = vfs_devblocksize(mp); +#else abp->f_bsize = mp->vfs_bsize; abp->f_iosize = mp->vfs_bsize; +#endif /* Fake a high number below to satisfy programs that use the statfs call * to make sure that there's enough space in the device partition before @@ -273,34 +383,111 @@ afs_statfs(struct mount *mp, struct statfs *abp, struct proc *p) abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files = abp->f_ffree = 2000000; - abp->f_fsid.val[0] = mp->mnt_stat.f_fsid.val[0]; - abp->f_fsid.val[1] = mp->mnt_stat.f_fsid.val[1]; - if (abp != &mp->mnt_stat) { - abp->f_type = mp->mnt_vfc->vfc_typenum; + if (abp != sysstat) { + abp->f_fsid.val[0] = sysstat->f_fsid.val[0]; + abp->f_fsid.val[1] = sysstat->f_fsid.val[1]; +#ifndef AFS_DARWIN80_ENV + abp->f_type = vfs_typenum(mp); +#endif memcpy((caddr_t) & abp->f_mntonname[0], - (caddr_t) mp->mnt_stat.f_mntonname, MNAMELEN); + (caddr_t) sysstat->f_mntonname, MNAMELEN); memcpy((caddr_t) & abp->f_mntfromname[0], - (caddr_t) mp->mnt_stat.f_mntfromname, MNAMELEN); + (caddr_t) sysstat->f_mntfromname, MNAMELEN); } AFS_GUNLOCK(); return 0; } +#ifdef AFS_DARWIN80_ENV +int +afs_vfs_getattr(struct mount *mp, struct vfs_attr *outattrs, + vfs_context_t context) +{ + VFSATTR_RETURN(outattrs, f_bsize, vfs_devblocksize(mp)); + VFSATTR_RETURN(outattrs, f_iosize, vfs_devblocksize(mp)); + VFSATTR_RETURN(outattrs, f_blocks, 2000000); + VFSATTR_RETURN(outattrs, f_bfree, 2000000); + VFSATTR_RETURN(outattrs, f_bavail, 2000000); + VFSATTR_RETURN(outattrs, f_files, 2000000); + VFSATTR_RETURN(outattrs, f_ffree, 2000000); + if ( VFSATTR_IS_ACTIVE(outattrs, f_capabilities) ) + { + vol_capabilities_attr_t *vcapattrptr; + vcapattrptr = &outattrs->f_capabilities; + vcapattrptr->capabilities[VOL_CAPABILITIES_FORMAT] = + VOL_CAP_FMT_SYMBOLICLINKS | + VOL_CAP_FMT_HARDLINKS | + VOL_CAP_FMT_ZERO_RUNS | + VOL_CAP_FMT_CASE_SENSITIVE | + VOL_CAP_FMT_CASE_PRESERVING | + VOL_CAP_FMT_FAST_STATFS; + vcapattrptr->capabilities[VOL_CAPABILITIES_INTERFACES] = + VOL_CAP_INT_ADVLOCK | + VOL_CAP_INT_FLOCK; + vcapattrptr->capabilities[VOL_CAPABILITIES_RESERVED1] = 0; + vcapattrptr->capabilities[VOL_CAPABILITIES_RESERVED2] = 0; + + /* Capabilities we know about: */ + vcapattrptr->valid[VOL_CAPABILITIES_FORMAT] = + VOL_CAP_FMT_PERSISTENTOBJECTIDS | + VOL_CAP_FMT_SYMBOLICLINKS | + VOL_CAP_FMT_HARDLINKS | + VOL_CAP_FMT_JOURNAL | + VOL_CAP_FMT_JOURNAL_ACTIVE | + VOL_CAP_FMT_NO_ROOT_TIMES | + VOL_CAP_FMT_SPARSE_FILES | + VOL_CAP_FMT_ZERO_RUNS | + VOL_CAP_FMT_CASE_SENSITIVE | + VOL_CAP_FMT_CASE_PRESERVING | + VOL_CAP_FMT_FAST_STATFS; + vcapattrptr->valid[VOL_CAPABILITIES_INTERFACES] = + VOL_CAP_INT_SEARCHFS | + VOL_CAP_INT_ATTRLIST | + VOL_CAP_INT_NFSEXPORT | + VOL_CAP_INT_READDIRATTR | + VOL_CAP_INT_EXCHANGEDATA | + VOL_CAP_INT_COPYFILE | + VOL_CAP_INT_ALLOCATE | + VOL_CAP_INT_VOL_RENAME | + VOL_CAP_INT_ADVLOCK | + VOL_CAP_INT_FLOCK; + vcapattrptr->valid[VOL_CAPABILITIES_RESERVED1] = 0; + vcapattrptr->valid[VOL_CAPABILITIES_RESERVED2] = 0; + + VFSATTR_SET_SUPPORTED(outattrs, f_capabilities); + } + return 0; +} +#endif + +#ifdef AFS_DARWIN80_ENV +int +afs_sync(mp, waitfor, ctx) + struct mount *mp; + int waitfor; + CTX_TYPE ctx; +#else int afs_sync(mp, waitfor, cred, p) struct mount *mp; int waitfor; struct ucred *cred; - struct prioc *p; + struct proc *p; +#endif { return 0; } u_int32_t afs_darwin_realmodes = 0; +#ifdef AFS_DARWIN80_ENV +int afs_sysctl(int *name, u_int namelen, user_addr_t oldp, size_t *oldlenp, + user_addr_t newp, size_t newlen, vfs_context_t context) +#else int afs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen, struct proc *p) +#endif { int error; @@ -315,8 +502,13 @@ int afs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, case AFS_SC_DARWIN_ALL: switch (name[2]) { case AFS_SC_DARWIN_ALL_REALMODES: +#ifdef AFS_DARWIN80_ENV + newlen; + /* XXX complicated */ +#else return sysctl_int(oldp, oldlenp, newp, newlen, &afs_darwin_realmodes); +#endif } break; /* darwin version specific sysctl's goes here */ @@ -332,6 +524,7 @@ extern struct vnodeopv_desc afs_vnodeop_opv_desc; int afs_init(struct vfsconf *vfc) { +#ifndef AFS_DARWIN80_ENV /* vfs_fsadd does all this junk */ int j; int (**opv_desc_vector) (); struct vnodeopv_entry_desc *opve_descp; @@ -393,19 +586,34 @@ afs_init(struct vfsconf *vfc) for (j = 0; j < vfs_opv_numops; j++) if (opv_desc_vector[j] == NULL) opv_desc_vector[j] = opv_desc_vector[VOFFSET(vop_default)]; +#endif + return 0; } struct vfsops afs_vfsops = { - afs_mount, - afs_start, - afs_unmount, - afs_root, - afs_quotactl, - afs_statfs, - afs_sync, - afs_vget, - afs_fhtovp, - afs_vptofh, - afs_init, - afs_sysctl + afs_mount, + afs_start, + afs_unmount, + afs_root, +#ifdef AFS_DARWIN80_ENV + 0, + afs_vfs_getattr, +#else + afs_quotactl, + afs_statfs, +#endif + afs_sync, +#ifdef AFS_DARWIN80_ENV + 0,0,0, +#else + afs_vfs_vget, + afs_fhtovp, + afs_vptofh, +#endif + afs_init, + afs_sysctl, +#ifdef AFS_DARWIN80_ENV + 0 /*setattr */, + {0} +#endif }; diff --git a/src/afs/DARWIN/osi_vm.c b/src/afs/DARWIN/osi_vm.c index 1285bf2f4..07a5d31e3 100644 --- a/src/afs/DARWIN/osi_vm.c +++ b/src/afs/DARWIN/osi_vm.c @@ -66,9 +66,13 @@ osi_VM_StoreAllSegments(struct vcache *avc) struct vnode *vp = AFSTOV(avc); ReleaseWriteLock(&avc->lock); AFS_GUNLOCK(); +#ifdef AFS_DARWIN80_ENV + ubc_sync_range(vp, 0, ubc_getsize(vp), UBC_SYNC|UBC_PUSHDIRTY); +#else if (UBCINFOEXISTS(vp)) { ubc_pushdirty(vp); } +#endif AFS_GLOCK(); ObtainWriteLock(&avc->lock, 94); } @@ -92,12 +96,16 @@ osi_VM_TryToSmush(struct vcache *avc, struct AFS_UCRED *acred, int sync) ReleaseWriteLock(&avc->lock); AFS_GUNLOCK(); +#ifdef AFS_DARWIN80_ENV + ubc_sync_range(vp, 0, ubc_getsize(vp), UBC_INVALIDATE); +#else if (UBCINFOEXISTS(vp)) { size = ubc_getsize(vp); kret = ubc_invalidate(vp, 0, size); if (kret != 1) /* should be KERN_SUCCESS */ printf("TryToSmush: invalidate failed (error = %d)\n", kret); } +#endif AFS_GLOCK(); ObtainWriteLock(&avc->lock, 59); } @@ -116,6 +124,13 @@ osi_VM_FlushPages(struct vcache *avc, struct AFS_UCRED *credp) void *object; kern_return_t kret; off_t size; +#ifdef AFS_DARWIN80_ENV + size = ubc_getsize(vp); + ubc_sync_range(vp, 0, size, UBC_INVALIDATE); + /* XXX what about when not CStatd */ + if (avc->states & CStatd && size != avc->m.Length) + ubc_setsize(vp, avc->m.Length); +#else if (UBCINFOEXISTS(vp)) { size = ubc_getsize(vp); kret = ubc_invalidate(vp, 0, size); @@ -126,6 +141,7 @@ osi_VM_FlushPages(struct vcache *avc, struct AFS_UCRED *credp) if (UBCISVALID(vp)) ubc_setsize(vp, avc->m.Length); } +#endif } /* Purge pages beyond end-of-file, when truncating a file. @@ -138,9 +154,13 @@ void osi_VM_Truncate(struct vcache *avc, int alen, struct AFS_UCRED *acred) { struct vnode *vp = AFSTOV(avc); +#ifdef AFS_DARWIN80_ENV + ubc_setsize(vp, alen); +#else if (UBCINFOEXISTS(vp) && UBCISVALID(vp)) { ubc_setsize(vp, alen); } +#endif } void @@ -167,6 +187,7 @@ osi_VM_Setup(struct vcache *avc, int force) int error; struct vnode *vp = AFSTOV(avc); +#ifndef AFS_DARWIN80_ENV if (UBCISVALID(vp) && ((avc->states & CStatd) || force)) { if (!UBCINFOEXISTS(vp)) { osi_vnhold(avc, 0); @@ -186,5 +207,6 @@ osi_VM_Setup(struct vcache *avc, int force) ubc_setsize(vp, avc->m.Length); } } +#endif return 0; } diff --git a/src/afs/DARWIN/osi_vnodeops.c b/src/afs/DARWIN/osi_vnodeops.c index 8fa5e0f91..bb8be243d 100644 --- a/src/afs/DARWIN/osi_vnodeops.c +++ b/src/afs/DARWIN/osi_vnodeops.c @@ -16,51 +16,81 @@ RCSID #if defined(AFS_DARWIN70_ENV) #include #endif /* defined(AFS_DARWIN70_ENV) */ +#ifdef AFS_DARWIN80_ENV +#include +#include +#endif + +#ifdef AFS_DARWIN80_ENV +#define VOPPREF(x) &vnop_ ## x +#define VOPPROT(x) vnop_ ## x +#define OSI_UPL_ABORT_RANGE(pl, offset, size, flags) \ + ubc_upl_abort_range((pl), (offset), (size), (flags)) +#define OSI_UPL_COMMIT_RANGE(pl, offset, size, flags) \ + ubc_upl_commit_range((pl), (offset), (size), (flags)) +#define OSI_UPL_MAP(upl, offset) ubc_upl_map((upl), (offset)) +#define OSI_UPL_UNMAP(upl) ubc_upl_unmap((upl)) +#define VOP_ABORTOP(x, y) +#else +#define VOPPREF(x) &vop_ ## x +#define VOPPROT(x) vop_ ## x +#define OSI_UPL_ABORT_RANGE(pl, offset, size, flags) \ + kernel_upl_abort_range((pl), (offset), (size), (flags)) +#define OSI_UPL_COMMIT_RANGE(pl, offset, size, flags) \ + kernel_upl_commit_range((pl), (offset), (size), (flags), \ + UPL_GET_INTERNAL_PAGE_LIST((pl)),\ + MAX_UPL_TRANSFER) +#define OSI_UPL_MAP(upl, offset) kernel_upl_map(kernel_map, (upl), (offset)) +#define OSI_UPL_UNMAP(upl) kernel_upl_unmap(kernel_map, (upl)) +#endif -int afs_vop_lookup(struct vop_lookup_args *); -int afs_vop_create(struct vop_create_args *); -int afs_vop_mknod(struct vop_mknod_args *); -int afs_vop_open(struct vop_open_args *); -int afs_vop_close(struct vop_close_args *); -int afs_vop_access(struct vop_access_args *); -int afs_vop_getattr(struct vop_getattr_args *); -int afs_vop_setattr(struct vop_setattr_args *); -int afs_vop_read(struct vop_read_args *); -int afs_vop_write(struct vop_write_args *); -int afs_vop_pagein(struct vop_pagein_args *); -int afs_vop_pageout(struct vop_pageout_args *); -int afs_vop_ioctl(struct vop_ioctl_args *); -int afs_vop_select(struct vop_select_args *); -int afs_vop_mmap(struct vop_mmap_args *); -int afs_vop_fsync(struct vop_fsync_args *); -int afs_vop_seek(struct vop_seek_args *); -int afs_vop_remove(struct vop_remove_args *); -int afs_vop_link(struct vop_link_args *); -int afs_vop_rename(struct vop_rename_args *); -int afs_vop_mkdir(struct vop_mkdir_args *); -int afs_vop_rmdir(struct vop_rmdir_args *); -int afs_vop_symlink(struct vop_symlink_args *); -int afs_vop_readdir(struct vop_readdir_args *); -int afs_vop_readlink(struct vop_readlink_args *); +extern char afs_zeros[AFS_ZEROS]; + +int afs_vop_lookup(struct VOPPROT(lookup_args) *); +int afs_vop_create(struct VOPPROT(create_args) *); +int afs_vop_mknod(struct VOPPROT(mknod_args) *); +int afs_vop_open(struct VOPPROT(open_args) *); +int afs_vop_close(struct VOPPROT(close_args) *); +int afs_vop_access(struct VOPPROT(access_args) *); +int afs_vop_getattr(struct VOPPROT(getattr_args) *); +int afs_vop_setattr(struct VOPPROT(setattr_args) *); +int afs_vop_read(struct VOPPROT(read_args) *); +int afs_vop_write(struct VOPPROT(write_args) *); +int afs_vop_pagein(struct VOPPROT(pagein_args) *); +int afs_vop_pageout(struct VOPPROT(pageout_args) *); +int afs_vop_ioctl(struct VOPPROT(ioctl_args) *); +int afs_vop_select(struct VOPPROT(select_args) *); +int afs_vop_mmap(struct VOPPROT(mmap_args) *); +int afs_vop_fsync(struct VOPPROT(fsync_args) *); +int afs_vop_remove(struct VOPPROT(remove_args) *); +int afs_vop_link(struct VOPPROT(link_args) *); +int afs_vop_rename(struct VOPPROT(rename_args) *); +int afs_vop_mkdir(struct VOPPROT(mkdir_args) *); +int afs_vop_rmdir(struct VOPPROT(rmdir_args) *); +int afs_vop_symlink(struct VOPPROT(symlink_args) *); +int afs_vop_readdir(struct VOPPROT(readdir_args) *); +int afs_vop_readlink(struct VOPPROT(readlink_args) *); #if !defined(AFS_DARWIN70_ENV) extern int ufs_abortop(struct vop_abortop_args *); #endif /* !defined(AFS_DARWIN70_ENV) */ -int afs_vop_inactive(struct vop_inactive_args *); -int afs_vop_reclaim(struct vop_reclaim_args *); -int afs_vop_lock(struct vop_lock_args *); -int afs_vop_unlock(struct vop_unlock_args *); -int afs_vop_bmap(struct vop_bmap_args *); -int afs_vop_strategy(struct vop_strategy_args *); -int afs_vop_print(struct vop_print_args *); -int afs_vop_islocked(struct vop_islocked_args *); -int afs_vop_pathconf(struct vop_pathconf_args *); -int afs_vop_advlock(struct vop_advlock_args *); -int afs_vop_truncate(struct vop_truncate_args *); -int afs_vop_update(struct vop_update_args *); -int afs_vop_blktooff __P((struct vop_blktooff_args *)); -int afs_vop_offtoblk __P((struct vop_offtoblk_args *)); -int afs_vop_cmap __P((struct vop_cmap_args *)); - +int afs_vop_inactive(struct VOPPROT(inactive_args) *); +int afs_vop_reclaim(struct VOPPROT(reclaim_args) *); +int afs_vop_strategy(struct VOPPROT(strategy_args) *); +int afs_vop_pathconf(struct VOPPROT(pathconf_args) *); +int afs_vop_advlock(struct VOPPROT(advlock_args) *); +int afs_vop_blktooff __P((struct VOPPROT(blktooff_args) *)); +int afs_vop_offtoblk __P((struct VOPPROT(offtoblk_args) *)); +#ifndef AFS_DARWIN80_ENV +int afs_vop_truncate(struct VOPPROT(truncate_args) *); +int afs_vop_update(struct VOPPROT(update_args) *); +int afs_vop_lock(struct VOPPROT(lock_args) *); +int afs_vop_unlock(struct VOPPROT(unlock_args) *); +int afs_vop_bmap(struct VOPPROT(bmap_args) *); +int afs_vop_seek(struct VOPPROT(seek_args) *); +int afs_vop_cmap __P((struct VOPPROT(cmap_args) *)); +int afs_vop_print(struct VOPPROT(print_args) *); +int afs_vop_islocked(struct VOPPROT(islocked_args) *); +#endif #define afs_vop_opnotsupp \ ((int (*) __P((struct vop_reallocblks_args *)))eopnotsupp) @@ -71,65 +101,126 @@ int afs_vop_cmap __P((struct vop_cmap_args *)); /* Global vfs data structures for AFS. */ int (**afs_vnodeop_p) (); + +#define VOPFUNC int (*)(void *) + struct vnodeopv_entry_desc afs_vnodeop_entries[] = { - {&vop_default_desc, vn_default_error}, - {&vop_lookup_desc, afs_vop_lookup}, /* lookup */ - {&vop_create_desc, afs_vop_create}, /* create */ - {&vop_mknod_desc, afs_vop_mknod}, /* mknod */ - {&vop_open_desc, afs_vop_open}, /* open */ - {&vop_close_desc, afs_vop_close}, /* close */ - {&vop_access_desc, afs_vop_access}, /* access */ - {&vop_getattr_desc, afs_vop_getattr}, /* getattr */ - {&vop_setattr_desc, afs_vop_setattr}, /* setattr */ - {&vop_read_desc, afs_vop_read}, /* read */ - {&vop_write_desc, afs_vop_write}, /* write */ - {&vop_pagein_desc, afs_vop_pagein}, /* read */ - {&vop_pageout_desc, afs_vop_pageout}, /* write */ - {&vop_ioctl_desc, afs_vop_ioctl}, /* XXX ioctl */ - {&vop_select_desc, afs_vop_select}, /* select */ - {&vop_mmap_desc, afs_vop_mmap}, /* mmap */ - {&vop_fsync_desc, afs_vop_fsync}, /* fsync */ - {&vop_seek_desc, afs_vop_seek}, /* seek */ - {&vop_remove_desc, afs_vop_remove}, /* remove */ - {&vop_link_desc, afs_vop_link}, /* link */ - {&vop_rename_desc, afs_vop_rename}, /* rename */ - {&vop_mkdir_desc, afs_vop_mkdir}, /* mkdir */ - {&vop_rmdir_desc, afs_vop_rmdir}, /* rmdir */ - {&vop_symlink_desc, afs_vop_symlink}, /* symlink */ - {&vop_readdir_desc, afs_vop_readdir}, /* readdir */ - {&vop_readlink_desc, afs_vop_readlink}, /* readlink */ + {VOPPREF(default_desc), (VOPFUNC)vn_default_error}, + {VOPPREF(lookup_desc), (VOPFUNC)afs_vop_lookup}, /* lookup */ + {VOPPREF(create_desc), (VOPFUNC)afs_vop_create}, /* create */ + {VOPPREF(mknod_desc), (VOPFUNC)afs_vop_mknod}, /* mknod */ + {VOPPREF(open_desc), (VOPFUNC)afs_vop_open}, /* open */ + {VOPPREF(close_desc), (VOPFUNC)afs_vop_close}, /* close */ + {VOPPREF(access_desc), (VOPFUNC)afs_vop_access}, /* access */ + {VOPPREF(getattr_desc), (VOPFUNC)afs_vop_getattr}, /* getattr */ + {VOPPREF(setattr_desc), (VOPFUNC)afs_vop_setattr}, /* setattr */ + {VOPPREF(read_desc), (VOPFUNC)afs_vop_read}, /* read */ + {VOPPREF(write_desc), (VOPFUNC)afs_vop_write}, /* write */ + {VOPPREF(pagein_desc), (VOPFUNC)afs_vop_pagein}, /* read */ + {VOPPREF(pageout_desc), (VOPFUNC)afs_vop_pageout}, /* write */ + {VOPPREF(ioctl_desc), (VOPFUNC)afs_vop_ioctl}, /* XXX ioctl */ + {VOPPREF(select_desc), (VOPFUNC)afs_vop_select}, /* select */ + {VOPPREF(mmap_desc), (VOPFUNC)afs_vop_mmap}, /* mmap */ + {VOPPREF(fsync_desc), (VOPFUNC)afs_vop_fsync}, /* fsync */ +#ifndef AFS_DARWIN80_ENV + {VOPPREF(seek_desc), (VOPFUNC)afs_vop_seek}, /* seek */ +#endif + {VOPPREF(remove_desc), (VOPFUNC)afs_vop_remove}, /* remove */ + {VOPPREF(link_desc), (VOPFUNC)afs_vop_link}, /* link */ + {VOPPREF(rename_desc), (VOPFUNC)afs_vop_rename}, /* rename */ + {VOPPREF(mkdir_desc), (VOPFUNC)afs_vop_mkdir}, /* mkdir */ + {VOPPREF(rmdir_desc), (VOPFUNC)afs_vop_rmdir}, /* rmdir */ + {VOPPREF(symlink_desc), (VOPFUNC)afs_vop_symlink}, /* symlink */ + {VOPPREF(readdir_desc), (VOPFUNC)afs_vop_readdir}, /* readdir */ + {VOPPREF(readlink_desc), (VOPFUNC)afs_vop_readlink}, /* readlink */ +#ifndef AFS_DARWIN80_ENV #if defined(AFS_DARWIN70_ENV) - { &vop_abortop_desc, nop_abortop }, /* abortop */ + {VOPPREF(abortop_desc), (VOPFUNC)nop_abortop }, /* abortop */ #else /* ! defined(AFS_DARWIN70_ENV) */ /* Yes, we use the ufs_abortop call. It just releases the namei * buffer stuff */ - {&vop_abortop_desc, ufs_abortop}, /* abortop */ + {VOPPREF(abortop_desc), (VOPFUNC)ufs_abortop}, /* abortop */ #endif /* defined(AFS_DARWIN70_ENV) */ - {&vop_inactive_desc, afs_vop_inactive}, /* inactive */ - {&vop_reclaim_desc, afs_vop_reclaim}, /* reclaim */ - {&vop_lock_desc, afs_vop_lock}, /* lock */ - {&vop_unlock_desc, afs_vop_unlock}, /* unlock */ - {&vop_bmap_desc, afs_vop_bmap}, /* bmap */ - {&vop_strategy_desc, afs_vop_strategy}, /* strategy */ - {&vop_print_desc, afs_vop_print}, /* print */ - {&vop_islocked_desc, afs_vop_islocked}, /* islocked */ - {&vop_pathconf_desc, afs_vop_pathconf}, /* pathconf */ - {&vop_advlock_desc, afs_vop_advlock}, /* advlock */ - {&vop_blkatoff_desc, afs_vop_blkatoff}, /* blkatoff */ - {&vop_valloc_desc, afs_vop_valloc}, /* valloc */ - {&vop_reallocblks_desc, afs_vop_reallocblks}, /* reallocblks */ - {&vop_vfree_desc, afs_vop_vfree}, /* vfree */ - {&vop_truncate_desc, afs_vop_truncate}, /* truncate */ - {&vop_update_desc, afs_vop_update}, /* update */ - {&vop_blktooff_desc, afs_vop_blktooff}, /* blktooff */ - {&vop_offtoblk_desc, afs_vop_offtoblk}, /* offtoblk */ - {&vop_cmap_desc, afs_vop_cmap}, /* cmap */ - {&vop_bwrite_desc, vn_bwrite}, - {(struct vnodeop_desc *)NULL, (int (*)())NULL} +#endif + {VOPPREF(inactive_desc), (VOPFUNC)afs_vop_inactive}, /* inactive */ + {VOPPREF(reclaim_desc), (VOPFUNC)afs_vop_reclaim}, /* reclaim */ +#ifndef AFS_DARWIN80_ENV + {VOPPREF(lock_desc), (VOPFUNC)afs_vop_lock}, /* lock */ + {VOPPREF(unlock_desc), (VOPFUNC)afs_vop_unlock}, /* unlock */ + {VOPPREF(bmap_desc), (VOPFUNC)afs_vop_bmap}, /* bmap */ +#endif +#ifdef AFS_DARWIN80_ENV + {VOPPREF(strategy_desc), (VOPFUNC)err_strategy}, /* strategy */ +#else + {VOPPREF(strategy_desc), (VOPFUNC)afs_vop_strategy}, /* strategy */ +#endif +#ifndef AFS_DARWIN80_ENV + {VOPPREF(print_desc), (VOPFUNC)afs_vop_print}, /* print */ + {VOPPREF(islocked_desc), (VOPFUNC)afs_vop_islocked}, /* islocked */ +#endif + {VOPPREF(pathconf_desc), (VOPFUNC)afs_vop_pathconf}, /* pathconf */ + {VOPPREF(advlock_desc), (VOPFUNC)afs_vop_advlock}, /* advlock */ +#ifndef AFS_DARWIN80_ENV + {VOPPREF(blkatoff_desc), (VOPFUNC)afs_vop_blkatoff}, /* blkatoff */ + {VOPPREF(valloc_desc), (VOPFUNC)afs_vop_valloc}, /* valloc */ + {VOPPREF(reallocblks_desc), (VOPFUNC)afs_vop_reallocblks}, /* reallocblks */ + {VOPPREF(vfree_desc), (VOPFUNC)afs_vop_vfree}, /* vfree */ + {VOPPREF(update_desc), (VOPFUNC)afs_vop_update}, /* update */ + {VOPPREF(cmap_desc), (VOPFUNC)afs_vop_cmap}, /* cmap */ + {VOPPREF(truncate_desc), (VOPFUNC)afs_vop_truncate}, /* truncate */ +#endif + {VOPPREF(blktooff_desc), (VOPFUNC)afs_vop_blktooff}, /* blktooff */ + {VOPPREF(offtoblk_desc), (VOPFUNC)afs_vop_offtoblk}, /* offtoblk */ + {VOPPREF(bwrite_desc), (VOPFUNC)vn_bwrite}, + {(struct vnodeop_desc *)NULL, (void (*)())NULL} }; struct vnodeopv_desc afs_vnodeop_opv_desc = { &afs_vnodeop_p, afs_vnodeop_entries }; +#ifdef AFS_DARWIN80_ENV +/* vfs structures for incompletely initialized vnodes */ +int (**afs_dead_vnodeop_p) (); + +struct vnodeopv_entry_desc afs_dead_vnodeop_entries[] = { + {VOPPREF(default_desc), (VOPFUNC)vn_default_error}, + {VOPPREF(lookup_desc), (VOPFUNC)vn_default_error}, /* lookup */ + {VOPPREF(create_desc), (VOPFUNC)err_create}, /* create */ + {VOPPREF(mknod_desc), (VOPFUNC)err_mknod}, /* mknod */ + {VOPPREF(open_desc), (VOPFUNC)err_open}, /* open */ + {VOPPREF(close_desc), (VOPFUNC)err_close}, /* close */ + {VOPPREF(access_desc), (VOPFUNC)err_access}, /* access */ + {VOPPREF(getattr_desc), (VOPFUNC)err_getattr}, /* getattr */ + {VOPPREF(setattr_desc), (VOPFUNC)err_setattr}, /* setattr */ + {VOPPREF(read_desc), (VOPFUNC)err_read}, /* read */ + {VOPPREF(write_desc), (VOPFUNC)err_write}, /* write */ + {VOPPREF(pagein_desc), (VOPFUNC)err_pagein}, /* read */ + {VOPPREF(pageout_desc), (VOPFUNC)err_pageout}, /* write */ + {VOPPREF(ioctl_desc), (VOPFUNC)err_ioctl}, /* XXX ioctl */ + {VOPPREF(select_desc), (VOPFUNC)nop_select}, /* select */ + {VOPPREF(mmap_desc), (VOPFUNC)err_mmap}, /* mmap */ + {VOPPREF(fsync_desc), (VOPFUNC)err_fsync}, /* fsync */ + {VOPPREF(remove_desc), (VOPFUNC)err_remove}, /* remove */ + {VOPPREF(link_desc), (VOPFUNC)err_link}, /* link */ + {VOPPREF(rename_desc), (VOPFUNC)err_rename}, /* rename */ + {VOPPREF(mkdir_desc), (VOPFUNC)err_mkdir}, /* mkdir */ + {VOPPREF(rmdir_desc), (VOPFUNC)err_rmdir}, /* rmdir */ + {VOPPREF(symlink_desc), (VOPFUNC)err_symlink}, /* symlink */ + {VOPPREF(readdir_desc), (VOPFUNC)err_readdir}, /* readdir */ + {VOPPREF(readlink_desc), (VOPFUNC)err_readlink}, /* readlink */ + {VOPPREF(inactive_desc), (VOPFUNC)afs_vop_inactive}, /* inactive */ + {VOPPREF(reclaim_desc), (VOPFUNC)afs_vop_reclaim}, /* reclaim */ + {VOPPREF(strategy_desc), (VOPFUNC)err_strategy}, /* strategy */ + {VOPPREF(pathconf_desc), (VOPFUNC)err_pathconf}, /* pathconf */ + {VOPPREF(advlock_desc), (VOPFUNC)err_advlock}, /* advlock */ + {VOPPREF(blktooff_desc), (VOPFUNC)err_blktooff}, /* blktooff */ + {VOPPREF(offtoblk_desc), (VOPFUNC)err_offtoblk}, /* offtoblk */ + {VOPPREF(bwrite_desc), (VOPFUNC)err_bwrite}, + {(struct vnodeop_desc *)NULL, (void (*)())NULL} +}; +struct vnodeopv_desc afs_dead_vnodeop_opv_desc = + { &afs_dead_vnodeop_p, afs_dead_vnodeop_entries }; +#endif + #define GETNAME() \ struct componentname *cnp = ap->a_cnp; \ char *name; \ @@ -145,30 +236,46 @@ darwin_vn_hold(struct vnode *vp) int haveGlock=ISAFS_GLOCK(); struct vcache *tvc = VTOAFS(vp); +#ifndef AFS_DARWIN80_ENV tvc->states |= CUBCinit; +#endif +#ifdef AFS_DARWIN80_ENV + if (tvc->states & CDeadVnode) + osi_Assert(!vnode_isinuse(vp, 1)); + osi_Assert((tvc->states & CVInit) == 0); +#endif if (haveGlock) AFS_GUNLOCK(); +#ifdef AFS_DARWIN80_ENV + vnode_get(vp); + vnode_ref(vp); + vnode_put(vp); +#else /* vget needed for 0 ref'd vnode in GetVCache to not panic in vref. vref needed for multiref'd vnode in vnop_remove not to deadlock ourselves during vop_inactive, except we also need to not reinst the ubc... so we just call VREF there now anyway. */ - if (VREFCOUNT(tvc) > 0) + if (VREFCOUNT_GT(tvc, 0)) VREF(((struct vnode *)(vp))); - else + else afs_vget(afs_globalVFS, 0, (vp)); +#endif +#ifndef AFS_DARWIN80_ENV if (UBCINFOMISSING(vp) || UBCINFORECLAIMED(vp)) { ubc_info_init(vp); } +#endif if (haveGlock) AFS_GLOCK(); +#ifndef AFS_DARWIN80_ENV tvc->states &= ~CUBCinit; +#endif } - int afs_vop_lookup(ap) - struct vop_lookup_args /* { + struct VOPPROT(lookup_args)/* { * struct vnodeop_desc * a_desc; * struct vnode *a_dvp; * struct vnode **a_vpp; @@ -182,42 +289,66 @@ afs_vop_lookup(ap) int lockparent; /* 1 => lockparent flag is set */ int wantparent; /* 1 => wantparent or lockparent flag */ struct proc *p; +#ifdef AFS_DARWIN80_ENV + error = cache_lookup(ap->a_dvp, ap->a_vpp, ap->a_cnp); + if (error == -1) + return 0; + if (error == ENOENT) + return error; +#endif + GETNAME(); - p = cnp->cn_proc; + p = vop_cn_proc; + lockparent = flags & LOCKPARENT; wantparent = flags & (LOCKPARENT | WANTPARENT); - if (ap->a_dvp->v_type != VDIR) { + if (!vnode_isdir(ap->a_dvp)) { *ap->a_vpp = 0; DROPNAME(); return ENOTDIR; } dvp = ap->a_dvp; +#ifndef AFS_DARWIN80_ENV if (flags & ISDOTDOT) VOP_UNLOCK(dvp, 0, p); +#endif AFS_GLOCK(); - error = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred); + error = afs_lookup(VTOAFS(dvp), name, &vcp, vop_cn_cred); AFS_GUNLOCK(); if (error) { +#ifndef AFS_DARWIN80_ENV if (flags & ISDOTDOT) VOP_LOCK(dvp, LK_EXCLUSIVE | LK_RETRY, p); +#endif if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) && (flags & ISLASTCN) && error == ENOENT) error = EJUSTRETURN; +#ifndef AFS_DARWIN80_ENV if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) cnp->cn_flags |= SAVENAME; +#endif DROPNAME(); *ap->a_vpp = 0; return (error); } +#ifdef AFS_DARWIN80_ENV + if ((error=afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0))) { + *ap->a_vpp = 0; + return error; + } +#endif vp = AFSTOV(vcp); /* always get a node if no error */ +#ifndef AFS_DARWIN80_ENV /* XXX needed for multi-mount thing, but can't have it yet */ vp->v_vfsp = dvp->v_vfsp; if (UBCINFOMISSING(vp) || UBCINFORECLAIMED(vp)) { ubc_info_init(vp); } +#endif +#ifndef AFS_DARWIN80_ENV /* The parent directory comes in locked. We unlock it on return * unless the caller wants it left locked. * we also always return the vnode locked. */ @@ -240,11 +371,14 @@ afs_vop_lookup(ap) vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); /* always return the child locked */ } +#endif *ap->a_vpp = vp; +#ifndef AFS_DARWIN80_ENV if ((cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN) || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)))) cnp->cn_flags |= SAVENAME; +#endif DROPNAME(); return error; @@ -252,7 +386,7 @@ afs_vop_lookup(ap) int afs_vop_create(ap) - struct vop_create_args /* { + struct VOPPROT(create_args) /* { * struct vnode *a_dvp; * struct vnode **a_vpp; * struct componentname *a_cnp; @@ -264,23 +398,32 @@ afs_vop_create(ap) register struct vnode *dvp = ap->a_dvp; struct proc *p; GETNAME(); - p = cnp->cn_proc; + p = vop_cn_proc; /* vnode layer handles excl/nonexcl */ AFS_GLOCK(); error = afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL, ap->a_vap->va_mode, - &vcp, cnp->cn_cred); + &vcp, vop_cn_cred); AFS_GUNLOCK(); if (error) { +#ifndef AFS_DARWIN80_ENV VOP_ABORTOP(dvp, cnp); vput(dvp); +#endif DROPNAME(); return (error); } if (vcp) { +#ifdef AFS_DARWIN80_ENV + if ((error=afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0))) { + *ap->a_vpp=0; + return error; + } +#endif *ap->a_vpp = AFSTOV(vcp); +#ifndef AFS_DARWIN80_ENV /* XXX needed for multi-mount thing, but can't have it yet */ (*ap->a_vpp)->v_vfsp = dvp->v_vfsp; vn_lock(*ap->a_vpp, LK_EXCLUSIVE | LK_RETRY, p); if (UBCINFOMISSING(*ap->a_vpp) || UBCINFORECLAIMED(*ap->a_vpp)) { @@ -288,33 +431,38 @@ afs_vop_create(ap) ubc_info_init(*ap->a_vpp); vcp->states &= ~CUBCinit; } +#endif } else *ap->a_vpp = 0; +#ifndef AFS_DARWIN80_ENV if ((cnp->cn_flags & SAVESTART) == 0) FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI); vput(dvp); +#endif DROPNAME(); return error; } int afs_vop_mknod(ap) - struct vop_mknod_args /* { + struct VOPPROT(mknod_args) /* { * struct vnode *a_dvp; * struct vnode **a_vpp; * struct componentname *a_cnp; * struct vattr *a_vap; * } */ *ap; { +#ifndef AFS_DARWIN80_ENV FREE_ZONE(ap->a_cnp->cn_pnbuf, ap->a_cnp->cn_pnlen, M_NAMEI); vput(ap->a_dvp); +#endif return (ENODEV); } int afs_vop_open(ap) - struct vop_open_args /* { + struct VOPPROT(open_args) /* { * struct vnode *a_vp; * int a_mode; * struct ucred *a_cred; @@ -324,7 +472,7 @@ afs_vop_open(ap) int error; struct vnode *vp = ap->a_vp; struct vcache *vc = VTOAFS(vp); -#ifdef AFS_DARWIN14_ENV +#if defined(AFS_DARWIN14_ENV) && !defined(AFS_DARWIN80_ENV) int didhold = 0; /*---------------------------------------------------------------- * osi_VM_TryReclaim() removes the ubcinfo of a vnode, but that vnode @@ -340,14 +488,14 @@ afs_vop_open(ap) didhold = ubc_hold(vp); #endif /* AFS_DARWIN14_ENV */ AFS_GLOCK(); - error = afs_open(&vc, ap->a_mode, ap->a_cred); + error = afs_open(&vc, ap->a_mode, vop_cred); #ifdef DIAGNOSTIC if (AFSTOV(vc) != vp) panic("AFS open changed vnode!"); #endif - osi_FlushPages(vc, ap->a_cred); + osi_FlushPages(vc, vop_cred); AFS_GUNLOCK(); -#ifdef AFS_DARWIN14_ENV +#if defined(AFS_DARWIN14_ENV) && !defined(AFS_DARWIN80_ENV) if (error && didhold) ubc_rele(vp); #endif /* AFS_DARWIN14_ENV */ @@ -356,7 +504,7 @@ afs_vop_open(ap) int afs_vop_close(ap) - struct vop_close_args /* { + struct VOPPROT(close_args) /* { * struct vnode *a_vp; * int a_fflag; * struct ucred *a_cred; @@ -367,19 +515,111 @@ afs_vop_close(ap) struct vnode *vp = ap->a_vp; struct vcache *avc = VTOAFS(vp); AFS_GLOCK(); - if (ap->a_cred) - code = afs_close(avc, ap->a_fflag, ap->a_cred, ap->a_p); + if (vop_cred) + code = afs_close(avc, ap->a_fflag, vop_cred, vop_proc); else - code = afs_close(avc, ap->a_fflag, &afs_osi_cred, ap->a_p); - osi_FlushPages(avc, ap->a_cred); /* hold bozon lock, but not basic vnode lock */ + code = afs_close(avc, ap->a_fflag, &afs_osi_cred, vop_proc); + osi_FlushPages(avc, vop_cred); /* hold bozon lock, but not basic vnode lock */ AFS_GUNLOCK(); return code; } +#ifdef AFS_DARWIN80_ENV +extern int afs_fakestat_enable; + int afs_vop_access(ap) - struct vop_access_args /* { + struct VOPPROT(access_args) /* { + * struct vnode *a_vp; + * int a_action; + * vfs_context_t a_context; + * } */ *ap; +{ + int code; + struct vrequest treq; + struct afs_fakestat_state fakestate; + struct vcache * tvc = VTOAFS(ap->a_vp); + int bits=0; + AFS_GLOCK(); + afs_InitFakeStat(&fakestate); + if ((code = afs_InitReq(&treq, vop_cred))) + goto out2; + + code = afs_TryEvalFakeStat(&tvc, &fakestate, &treq); + if (code) { + code = afs_CheckCode(code, &treq, 55); + goto out; + } + + code = afs_VerifyVCache(tvc, &treq); + if (code) { + code = afs_CheckCode(code, &treq, 56); + goto out; + } + if (afs_fakestat_enable && tvc->mvstat && !(tvc->states & CStatd)) { + code = 0; + goto out; + } + if (vnode_isdir(ap->a_vp)) { + if (ap->a_action & KAUTH_VNODE_LIST_DIRECTORY) + bits |= PRSFS_LOOKUP; + if (ap->a_action & KAUTH_VNODE_ADD_FILE) + bits |= PRSFS_INSERT; + if (ap->a_action & KAUTH_VNODE_SEARCH) + bits |= PRSFS_LOOKUP; + if (ap->a_action & KAUTH_VNODE_DELETE) + bits |= PRSFS_DELETE; + if (ap->a_action & KAUTH_VNODE_ADD_SUBDIRECTORY) + bits |= PRSFS_INSERT; + if (ap->a_action & KAUTH_VNODE_DELETE_CHILD) + bits |= PRSFS_DELETE; + } else { + if (ap->a_action & KAUTH_VNODE_READ_DATA) + bits |= PRSFS_READ; + if (ap->a_action & KAUTH_VNODE_WRITE_DATA) + bits |= PRSFS_WRITE; + if (ap->a_action & KAUTH_VNODE_EXECUTE) + bits |= PRSFS_READ; /* and mode bits.... */ + } + if (ap->a_action & KAUTH_VNODE_READ_ATTRIBUTES) + bits |= PRSFS_READ; + if (ap->a_action & KAUTH_VNODE_WRITE_ATTRIBUTES) + bits |= PRSFS_WRITE; +#if 0 /* no extended attributes */ + if (ap->a_action & KAUTH_VNODE_READ_EXTATTRIBUTES) + bits |= PRSFS_READ; + if (ap->a_action & KAUTH_VNODE_WRITE_EXTATTRIBUTES) + bits |= PRSFS_WRITE; +#endif + if (ap->a_action & KAUTH_VNODE_READ_SECURITY) /* mode bits/gid, not afs acl */ + bits |= PRSFS_READ; + if (ap->a_action & KAUTH_VNODE_WRITE_SECURITY) + bits |= PRSFS_WRITE; + /* we can't check for KAUTH_VNODE_TAKE_OWNERSHIP, so we always permit it */ + + code = afs_AccessOK(tvc, bits, &treq, CHECK_MODE_BITS); + + if (code == 1 && vnode_vtype(ap->a_vp) == VREG && + ap->a_action & KAUTH_VNODE_EXECUTE && + (tvc->m.Mode & 0100) != 0100) { + code = 0; + } + if (code) { + code= 0; /* if access is ok */ + } else { + code = afs_CheckCode(EACCES, &treq, 57); /* failure code */ + } +out: + afs_PutFakeStat(&fakestate); +out2: + AFS_GUNLOCK(); + return code; +} +#else +int +afs_vop_access(ap) + struct VOPPROT(access_args) /* { * struct vnode *a_vp; * int a_mode; * struct ucred *a_cred; @@ -388,14 +628,15 @@ afs_vop_access(ap) { int code; AFS_GLOCK(); - code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred); + code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, vop_cred); AFS_GUNLOCK(); return code; } +#endif int afs_vop_getattr(ap) - struct vop_getattr_args /* { + struct VOPPROT(getattr_args) /* { * struct vnode *a_vp; * struct vattr *a_vap; * struct ucred *a_cred; @@ -405,14 +646,30 @@ afs_vop_getattr(ap) int code; AFS_GLOCK(); - code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred); + code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, vop_cred); AFS_GUNLOCK(); +#ifdef AFS_DARWIN80_ENV + VATTR_SET_SUPPORTED(ap->a_vap, va_type); + VATTR_SET_SUPPORTED(ap->a_vap, va_mode); + VATTR_SET_SUPPORTED(ap->a_vap, va_uid); + VATTR_SET_SUPPORTED(ap->a_vap, va_gid); + VATTR_SET_SUPPORTED(ap->a_vap, va_fileid); + VATTR_SET_SUPPORTED(ap->a_vap, va_nlink); + VATTR_SET_SUPPORTED(ap->a_vap, va_data_size); + VATTR_SET_SUPPORTED(ap->a_vap, va_access_time); + VATTR_SET_SUPPORTED(ap->a_vap, va_modify_time); + VATTR_SET_SUPPORTED(ap->a_vap, va_change_time); + VATTR_SET_SUPPORTED(ap->a_vap, va_gen); + VATTR_SET_SUPPORTED(ap->a_vap, va_flags); + VATTR_SET_SUPPORTED(ap->a_vap, va_iosize); + VATTR_SET_SUPPORTED(ap->a_vap, va_total_alloc); +#endif return code; } int afs_vop_setattr(ap) - struct vop_setattr_args /* { + struct VOPPROT(setattr_args) /* { * struct vnode *a_vp; * struct vattr *a_vap; * struct ucred *a_cred; @@ -421,14 +678,14 @@ afs_vop_setattr(ap) { int code; AFS_GLOCK(); - code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred); + code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, vop_cred); AFS_GUNLOCK(); return code; } int afs_vop_read(ap) - struct vop_read_args /* { + struct VOPPROT(read_args) /* { * struct vnode *a_vp; * struct uio *a_uio; * int a_ioflag; @@ -438,16 +695,23 @@ afs_vop_read(ap) int code; struct vnode *vp = ap->a_vp; struct vcache *avc = VTOAFS(vp); +#ifdef AFS_DARWIN80_ENV + ubc_sync_range(ap->a_vp, AFS_UIO_OFFSET(ap->a_uio), AFS_UIO_OFFSET(ap->a_uio) + AFS_UIO_RESID(ap->a_uio), UBC_PUSHDIRTY); +#else + if (UBCINFOEXISTS(ap->a_vp)) { + ubc_clean(ap->a_vp, 0); + } +#endif AFS_GLOCK(); - osi_FlushPages(avc, ap->a_cred); /* hold bozon lock, but not basic vnode lock */ - code = afs_read(avc, ap->a_uio, ap->a_cred, 0, 0, 0); + osi_FlushPages(avc, vop_cred); /* hold bozon lock, but not basic vnode lock */ + code = afs_read(avc, ap->a_uio, vop_cred, 0, 0, 0); AFS_GUNLOCK(); return code; } int afs_vop_pagein(ap) - struct vop_pagein_args /* { + struct VOPPROT(pagein_args) /* { * struct vnode *a_vp; * upl_t a_pl; * vm_offset_t a_pl_offset; @@ -465,14 +729,18 @@ afs_vop_pagein(ap) int flags = ap->a_flags; struct ucred *cred; vm_offset_t ioaddr; +#ifdef AFS_DARWIN80_ENV + struct uio *uio; +#else struct uio auio; struct iovec aiov; struct uio *uio = &auio; +#endif int nocommit = flags & UPL_NOCOMMIT; int code; struct vcache *tvc = VTOAFS(vp); - +#ifndef AFS_DARWIN80_ENV if (UBCINVALID(vp)) { #if DIAGNOSTIC panic("afs_vop_pagein: invalid vp"); @@ -481,41 +749,47 @@ afs_vop_pagein(ap) } UBCINFOCHECK("afs_vop_pagein", vp); +#endif if (pl == (upl_t) NULL) { panic("afs_vop_pagein: no upl"); } cred = ubc_getcred(vp); if (cred == NOCRED) - cred = ap->a_cred; + cred = vop_cred; if (size == 0) { if (!nocommit) - kernel_upl_abort_range(pl, pl_offset, size, + OSI_UPL_ABORT_RANGE(pl, pl_offset, size, UPL_ABORT_ERROR | UPL_ABORT_FREE_ON_EMPTY); return (0); } if (f_offset < 0) { if (!nocommit) - kernel_upl_abort_range(pl, pl_offset, size, + OSI_UPL_ABORT_RANGE(pl, pl_offset, size, UPL_ABORT_ERROR | UPL_ABORT_FREE_ON_EMPTY); return (EINVAL); } if (f_offset & PAGE_MASK) panic("afs_vop_pagein: offset not page aligned"); + OSI_UPL_MAP(pl, &ioaddr); + ioaddr += pl_offset; +#ifdef AFS_DARWIN80_ENV + uio = uio_create(1, f_offset, UIO_SYSSPACE32, UIO_READ); + uio_addiov(uio, CAST_USER_ADDR_T(ioaddr), size); +#else auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_offset = f_offset; auio.uio_segflg = UIO_SYSSPACE; auio.uio_rw = UIO_READ; auio.uio_procp = NULL; - kernel_upl_map(kernel_map, pl, &ioaddr); - ioaddr += pl_offset; auio.uio_resid = aiov.iov_len = size; aiov.iov_base = (caddr_t) ioaddr; +#endif AFS_GLOCK(); - osi_FlushPages(tvc, ap->a_cred); /* hold bozon lock, but not basic vnode lock */ + osi_FlushPages(tvc, vop_cred); /* hold bozon lock, but not basic vnode lock */ code = afs_read(tvc, uio, cred, 0, 0, 0); if (code == 0) { ObtainWriteLock(&tvc->lock, 2); @@ -525,27 +799,34 @@ afs_vop_pagein(ap) AFS_GUNLOCK(); /* Zero out rest of last page if there wasn't enough data in the file */ - if (code == 0 && auio.uio_resid > 0) + if (code == 0 && AFS_UIO_RESID(uio) > 0) { +#ifdef AFS_DARWIN80_ENV + memset(((caddr_t)ioaddr) + (size - AFS_UIO_RESID(uio)), 0, + AFS_UIO_RESID(uio)); +#else memset(aiov.iov_base, 0, auio.uio_resid); +#endif + } - kernel_upl_unmap(kernel_map, pl); + OSI_UPL_UNMAP(pl); if (!nocommit) { if (code) - kernel_upl_abort_range(pl, pl_offset, size, + OSI_UPL_ABORT_RANGE(pl, pl_offset, size, UPL_ABORT_ERROR | UPL_ABORT_FREE_ON_EMPTY); else - kernel_upl_commit_range(pl, pl_offset, size, + OSI_UPL_COMMIT_RANGE(pl, pl_offset, size, UPL_COMMIT_CLEAR_DIRTY | - UPL_COMMIT_FREE_ON_EMPTY, - UPL_GET_INTERNAL_PAGE_LIST(pl), - MAX_UPL_TRANSFER); + UPL_COMMIT_FREE_ON_EMPTY); } +#ifdef AFS_DARWIN80_ENV + uio_free(uio); +#endif return code; } int afs_vop_write(ap) - struct vop_write_args /* { + struct VOPPROT(write_args) /* { * struct vnode *a_vp; * struct uio *a_uio; * int a_ioflag; @@ -555,23 +836,27 @@ afs_vop_write(ap) int code; struct vcache *avc = VTOAFS(ap->a_vp); void *object; - AFS_GLOCK(); - osi_FlushPages(avc, ap->a_cred); /* hold bozon lock, but not basic vnode lock */ +#ifdef AFS_DARWIN80_ENV + ubc_sync_range(ap->a_vp, AFS_UIO_OFFSET(ap->a_uio), AFS_UIO_OFFSET(ap->a_uio) + AFS_UIO_RESID(ap->a_uio), UBC_INVALIDATE); +#else if (UBCINFOEXISTS(ap->a_vp)) { ubc_clean(ap->a_vp, 1); } if (UBCINFOEXISTS(ap->a_vp)) - osi_VM_NukePages(ap->a_vp, ap->a_uio->uio_offset, - ap->a_uio->uio_resid); + osi_VM_NukePages(ap->a_vp, AFS_UIO_OFFSET(ap->a_uio), + AFS_UIO_RESID(ap->a_uio)); +#endif + AFS_GLOCK(); + osi_FlushPages(avc, vop_cred); /* hold bozon lock, but not basic vnode lock */ code = - afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0); + afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, vop_cred, 0); AFS_GUNLOCK(); return code; } int afs_vop_pageout(ap) - struct vop_pageout_args /* { + struct VOPPROT(pageout_args) /* { * struct vnode *a_vp; * upl_t a_pl, * vm_offset_t a_pl_offset, @@ -589,15 +874,19 @@ afs_vop_pageout(ap) int flags = ap->a_flags; struct ucred *cred; vm_offset_t ioaddr; +#ifdef AFS_DARWIN80_ENV + struct uio *uio; +#else struct uio auio; struct iovec aiov; struct uio *uio = &auio; +#endif int nocommit = flags & UPL_NOCOMMIT; int iosize; int code; struct vcache *tvc = VTOAFS(vp); - +#ifndef AFS_DARWIN80_ENV if (UBCINVALID(vp)) { #if DIAGNOSTIC panic("afs_vop_pageout: invalid vp"); @@ -606,10 +895,14 @@ afs_vop_pageout(ap) } UBCINFOCHECK("afs_vop_pageout", vp); +#endif if (pl == (upl_t) NULL) { panic("afs_vop_pageout: no upl"); } -#if 1 +#if !defined(AFS_DARWIN80_ENV) /* XXX nfs now uses it's own bufs (struct nfsbuf) + maybe the generic + layer doesn't have them anymore? In any case, + we can't just copy code from nfs... */ { int lbn, s; struct buf *bp; @@ -634,11 +927,11 @@ afs_vop_pageout(ap) #endif cred = ubc_getcred(vp); if (cred == NOCRED) - cred = ap->a_cred; + cred = vop_cred; if (size == 0) { if (!nocommit) - kernel_upl_abort_range(pl, pl_offset, size, + OSI_UPL_ABORT_RANGE(pl, pl_offset, size, UPL_ABORT_FREE_ON_EMPTY); return (0); } @@ -646,13 +939,13 @@ afs_vop_pageout(ap) panic("nfs_pageout: (IO_APPEND | IO_SYNC)"); if (f_offset < 0) { if (!nocommit) - kernel_upl_abort_range(pl, pl_offset, size, + OSI_UPL_ABORT_RANGE(pl, pl_offset, size, UPL_ABORT_FREE_ON_EMPTY); return (EINVAL); } if (f_offset >= tvc->m.Length) { if (!nocommit) - kernel_upl_abort_range(pl, pl_offset, size, + OSI_UPL_ABORT_RANGE(pl, pl_offset, size, UPL_ABORT_FREE_ON_EMPTY); return (EINVAL); } @@ -669,20 +962,25 @@ afs_vop_pageout(ap) if (size > (iosize + (PAGE_SIZE - 1)) & ~PAGE_MASK && !nocommit) { int iosize_rnd=(iosize + (PAGE_SIZE - 1)) & ~PAGE_MASK; - kernel_upl_abort_range(pl, pl_offset + iosize_rnd, + OSI_UPL_ABORT_RANGE(pl, pl_offset + iosize_rnd, size - iosize_rnd, UPL_ABORT_FREE_ON_EMPTY); } + OSI_UPL_MAP(pl, &ioaddr); + ioaddr += pl_offset; +#ifdef AFS_DARWIN80_ENV + uio = uio_create(1, f_offset, UIO_SYSSPACE32, UIO_READ); + uio_addiov(uio, CAST_USER_ADDR_T(ioaddr), size); +#else auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_offset = f_offset; auio.uio_segflg = UIO_SYSSPACE; auio.uio_rw = UIO_WRITE; auio.uio_procp = NULL; - kernel_upl_map(kernel_map, pl, &ioaddr); - ioaddr += pl_offset; auio.uio_resid = aiov.iov_len = iosize; aiov.iov_base = (caddr_t) ioaddr; +#endif #if 1 /* USV [ */ { /* @@ -699,7 +997,7 @@ afs_vop_pageout(ap) #endif /* ] USV */ AFS_GLOCK(); - osi_FlushPages(tvc, ap->a_cred); /* hold bozon lock, but not basic vnode lock */ + osi_FlushPages(tvc, vop_cred); /* hold bozon lock, but not basic vnode lock */ ObtainWriteLock(&tvc->lock, 1); afs_FakeOpen(tvc); ReleaseWriteLock(&tvc->lock); @@ -710,25 +1008,26 @@ afs_vop_pageout(ap) afs_FakeClose(tvc, cred); ReleaseWriteLock(&tvc->lock); AFS_GUNLOCK(); - kernel_upl_unmap(kernel_map, pl); + OSI_UPL_UNMAP(pl); if (!nocommit) { if (code) - kernel_upl_abort_range(pl, pl_offset, size, + OSI_UPL_ABORT_RANGE(pl, pl_offset, size, UPL_ABORT_FREE_ON_EMPTY); else - kernel_upl_commit_range(pl, pl_offset, size, + OSI_UPL_COMMIT_RANGE(pl, pl_offset, size, UPL_COMMIT_CLEAR_DIRTY | - UPL_COMMIT_FREE_ON_EMPTY, - UPL_GET_INTERNAL_PAGE_LIST(pl), - MAX_UPL_TRANSFER); + UPL_COMMIT_FREE_ON_EMPTY); } +#ifdef AFS_DARWIN80_ENV + uio_free(uio); +#endif return code; } int afs_vop_ioctl(ap) - struct vop_ioctl_args /* { + struct VOPPROT(ioctl_args) /* { * struct vnode *a_vp; * int a_command; * caddr_t a_data; @@ -760,7 +1059,7 @@ afs_vop_ioctl(ap) /* ARGSUSED */ int afs_vop_select(ap) - struct vop_select_args /* { + struct VOPPROT(select_args) /* { * struct vnode *a_vp; * int a_which; * int a_fflags; @@ -782,7 +1081,7 @@ afs_vop_select(ap) /* ARGSUSED */ int afs_vop_mmap(ap) - struct vop_mmap_args /* { + struct VOPPROT(mmap_args) /* { * struct vnode *a_vp; * int a_fflags; * struct ucred *a_cred; @@ -794,7 +1093,7 @@ afs_vop_mmap(ap) int afs_vop_fsync(ap) - struct vop_fsync_args /* { + struct VOPPROT(fsync_args) /* { * struct vnode *a_vp; * struct ucred *a_cred; * int a_waitfor; @@ -808,17 +1107,18 @@ afs_vop_fsync(ap) /* afs_vop_lookup glocks, can call us through vinvalbuf from GetVCache */ if (!haveGlock) AFS_GLOCK(); - if (ap->a_cred) - error = afs_fsync(VTOAFS(vp), ap->a_cred); + if (vop_cred) + error = afs_fsync(VTOAFS(vp), vop_cred); else error = afs_fsync(VTOAFS(vp), &afs_osi_cred); if (!haveGlock) AFS_GUNLOCK(); return error; } +#ifndef AFS_DARWIN80_ENV int afs_vop_seek(ap) - struct vop_seek_args /* { + struct VOPPROT(seek_args) /* { * struct vnode *a_vp; * off_t a_oldoff; * off_t a_newoff; @@ -829,10 +1129,11 @@ afs_vop_seek(ap) return EINVAL; return (0); } +#endif int afs_vop_remove(ap) - struct vop_remove_args /* { + struct VOPPROT(remove_args) /* { * struct vnode *a_dvp; * struct vnode *a_vp; * struct componentname *a_cnp; @@ -842,33 +1143,51 @@ afs_vop_remove(ap) register struct vnode *vp = ap->a_vp; register struct vnode *dvp = ap->a_dvp; +#ifdef AFS_DARWIN80_ENV + if (ap->a_flags & VNODE_REMOVE_NODELETEBUSY) { + /* Caller requested Carbon delete semantics */ + if (vnode_isinuse(vp, 0)) { + return EBUSY; + } + } +#endif + GETNAME(); AFS_GLOCK(); - error = afs_remove(VTOAFS(dvp), name, cnp->cn_cred); + error = afs_remove(VTOAFS(dvp), name, vop_cn_cred); AFS_GUNLOCK(); cache_purge(vp); - vput(dvp); if (!error) { +#ifdef AFS_DARWIN80_ENV + ubc_setsize(vp, (off_t)0); + vnode_recycle(vp); +#else /* necessary so we don't deadlock ourselves in vclean */ VOP_UNLOCK(vp, 0, cnp->cn_proc); /* If crashes continue in ubc_hold, comment this out */ (void)ubc_uncache(vp); +#endif } +#ifndef AFS_DARWIN80_ENV + vput(dvp); if (dvp == vp) vrele(vp); else vput(vp); +#endif +#ifndef AFS_DARWIN80_ENV FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI); +#endif DROPNAME(); return error; } int afs_vop_link(ap) - struct vop_link_args /* { + struct VOPPROT(link_args) /* { * struct vnode *a_vp; * struct vnode *a_tdvp; * struct componentname *a_cnp; @@ -880,31 +1199,39 @@ afs_vop_link(ap) struct proc *p; GETNAME(); - p = cnp->cn_proc; - if (vp->v_type == VDIR) { + p = vop_cn_proc; + if (vnode_isdir(vp)) { VOP_ABORTOP(vp, cnp); error = EISDIR; goto out; } +#ifndef AFS_DARWIN80_ENV if (error = vn_lock(vp, LK_EXCLUSIVE, p)) { VOP_ABORTOP(dvp, cnp); goto out; } +#endif AFS_GLOCK(); - error = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred); + error = afs_link(VTOAFS(vp), VTOAFS(dvp), name, vop_cn_cred); AFS_GUNLOCK(); +#ifndef AFS_DARWIN80_ENV FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI); +#endif +#ifndef AFS_DARWIN80_ENV if (dvp != vp) VOP_UNLOCK(vp, 0, p); +#endif out: +#ifndef AFS_DARWIN80_ENV vput(dvp); +#endif DROPNAME(); return error; } int afs_vop_rename(ap) - struct vop_rename_args /* { + struct VOPPROT(rename_args) /* { * struct vnode *a_fdvp; * struct vnode *a_fvp; * struct componentname *a_fcnp; @@ -922,8 +1249,15 @@ afs_vop_rename(ap) register struct vnode *tdvp = ap->a_tdvp; struct vnode *fvp = ap->a_fvp; register struct vnode *fdvp = ap->a_fdvp; - struct proc *p = fcnp->cn_proc; + struct proc *p; + + p = cn_proc(fcnp); +#ifdef AFS_DARWIN80_ENV +/* generic code tests for v_mount equality, so we don't have to, but we don't + get the multiple-mount "benefits" of the old behavior +*/ +#else /* Check for cross-device rename. * For AFS, this means anything not in AFS-space */ @@ -932,14 +1266,19 @@ afs_vop_rename(ap) error = EXDEV; goto abortit; } +#endif +#ifdef AFS_DARWIN80_ENV + /* the generic code doesn't do this, so we really should, but all the + vrele's are wrong... */ +#else /* * if fvp == tvp, we're just removing one name of a pair of * directory entries for the same element. convert call into rename. ( (pinched from NetBSD 1.0's ufs_rename()) */ if (fvp == tvp) { - if (fvp->v_type == VDIR) { + if (vnode_isdir(fvp)) { error = EINVAL; abortit: VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */ @@ -959,8 +1298,18 @@ afs_vop_rename(ap) VOP_ABORTOP(tdvp, tcnp); vput(tdvp); vput(tvp); - /* Delete source. */ +#if defined(AFS_DARWIN80_ENV) + + MALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK); + memcpy(fname, fcnp->cn_nameptr, fcnp->cn_namelen); + fname[fcnp->cn_namelen] = '\0'; + AFS_GLOCK(); + error = afs_remove(VTOAFS(fdvp), fname, vop_cn_cred); + AFS_GUNLOCK(); + FREE(fname, M_TEMP); + cache_purge(fvp); +#else vrele(fdvp); vrele(fvp); fcnp->cn_flags &= ~MODMASK; @@ -976,8 +1325,9 @@ afs_vop_rename(ap) if (fvp == NULL) { return (ENOENT); } - error=VOP_REMOVE(fdvp, fvp, fcnp); +#endif + if (fdvp == fvp) vrele(fdvp); else @@ -985,8 +1335,11 @@ afs_vop_rename(ap) vput(fvp); return (error); } +#endif +#if !defined(AFS_DARWIN80_ENV) if (error = vn_lock(fvp, LK_EXCLUSIVE, p)) goto abortit; +#endif MALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK); memcpy(fname, fcnp->cn_nameptr, fcnp->cn_namelen); @@ -999,12 +1352,27 @@ afs_vop_rename(ap) AFS_GLOCK(); /* XXX use "from" or "to" creds? NFS uses "to" creds */ error = - afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred); + afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, cn_cred(tcnp)); AFS_GUNLOCK(); +#if !defined(AFS_DARWIN80_ENV) VOP_UNLOCK(fvp, 0, p); +#endif FREE(fname, M_TEMP); FREE(tname, M_TEMP); +#ifdef AFS_DARWIN80_ENV + cache_purge(fdvp); + cache_purge(fvp); + cache_purge(tdvp); + if (tvp) { + cache_purge(tvp); + if (!error) { + vnode_recycle(tvp); + } + } + if (!error) + cache_enter(tdvp, fvp, tcnp); +#else if (error) goto abortit; /* XXX */ if (tdvp == tvp) @@ -1015,12 +1383,13 @@ afs_vop_rename(ap) vput(tvp); vrele(fdvp); vrele(fvp); +#endif return error; } int afs_vop_mkdir(ap) - struct vop_mkdir_args /* { + struct VOPPROT(mkdir_args) /* { * struct vnode *a_dvp; * struct vnode **a_vpp; * struct componentname *a_cnp; @@ -1034,13 +1403,13 @@ afs_vop_mkdir(ap) struct proc *p; GETNAME(); - p = cnp->cn_proc; -#ifdef DIAGNOSTIC + p = vop_cn_proc; +#if defined(DIAGNOSTIC) && !defined(AFS_DARWIN80_ENV) if ((cnp->cn_flags & HASBUF) == 0) panic("afs_vop_mkdir: no name"); #endif AFS_GLOCK(); - error = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred); + error = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, vop_cn_cred); AFS_GUNLOCK(); if (error) { VOP_ABORTOP(dvp, cnp); @@ -1049,20 +1418,27 @@ afs_vop_mkdir(ap) return (error); } if (vcp) { +#ifdef AFS_DARWIN80_ENV + afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0); +#endif *ap->a_vpp = AFSTOV(vcp); +#ifndef AFS_DARWIN80_ENV /* XXX needed for multi-mount thing, but can't have it yet */ (*ap->a_vpp)->v_vfsp = dvp->v_vfsp; vn_lock(*ap->a_vpp, LK_EXCLUSIVE | LK_RETRY, p); +#endif } else *ap->a_vpp = 0; DROPNAME(); +#ifndef AFS_DARWIN80_ENV FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI); vput(dvp); +#endif return error; } int afs_vop_rmdir(ap) - struct vop_rmdir_args /* { + struct VOPPROT(rmdir_args) /* { * struct vnode *a_dvp; * struct vnode *a_vp; * struct componentname *a_cnp; @@ -1074,25 +1450,31 @@ afs_vop_rmdir(ap) GETNAME(); if (dvp == vp) { +#ifndef AFS_DARWIN80_ENV vrele(dvp); vput(vp); FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI); +#endif DROPNAME(); return (EINVAL); } AFS_GLOCK(); - error = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred); + error = afs_rmdir(VTOAFS(dvp), name, vop_cn_cred); AFS_GUNLOCK(); DROPNAME(); + cache_purge(dvp); + cache_purge(vp); +#ifndef AFS_DARWIN80_ENV vput(dvp); vput(vp); +#endif return error; } int afs_vop_symlink(ap) - struct vop_symlink_args /* { + struct VOPPROT(symlink_args) /* { * struct vnode *a_dvp; * struct vnode **a_vpp; * struct componentname *a_cnp; @@ -1107,17 +1489,19 @@ afs_vop_symlink(ap) GETNAME(); AFS_GLOCK(); error = - afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, cnp->cn_cred); + afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, vop_cn_cred); AFS_GUNLOCK(); DROPNAME(); +#ifndef AFS_DARWIN80_ENV FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI); vput(dvp); +#endif return error; } int afs_vop_readdir(ap) - struct vop_readdir_args /* { + struct VOPPROT(readdir_args) /* { * struct vnode *a_vp; * struct uio *a_uio; * struct ucred *a_cred; @@ -1130,11 +1514,18 @@ afs_vop_readdir(ap) off_t off; /* printf("readdir %x cookies %x ncookies %d\n", ap->a_vp, ap->a_cookies, ap->a_ncookies); */ - off = ap->a_uio->uio_offset; +#ifdef AFS_DARWIN80_ENV + /* too much work for now */ + /* should only break nfs exports */ + if (ap->a_flags & (VNODE_READDIR_EXTENDED | VNODE_READDIR_REQSEEKOFF)) + return (EINVAL); +#endif + off = AFS_UIO_OFFSET(ap->a_uio); AFS_GLOCK(); error = - afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag); + afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, vop_cred, ap->a_eofflag); AFS_GUNLOCK(); +#ifndef AFS_DARWIN80_ENV if (!error && ap->a_ncookies != NULL) { struct uio *uio = ap->a_uio; const struct dirent *dp, *dp_start, *dp_end; @@ -1161,13 +1552,14 @@ afs_vop_readdir(ap) *ap->a_cookies = cookies; *ap->a_ncookies = ncookies; } +#endif return error; } int afs_vop_readlink(ap) - struct vop_readlink_args /* { + struct VOPPROT(readlink_args) /* { * struct vnode *a_vp; * struct uio *a_uio; * struct ucred *a_cred; @@ -1176,7 +1568,7 @@ afs_vop_readlink(ap) int error; /* printf("readlink %x\n", ap->a_vp);*/ AFS_GLOCK(); - error = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred); + error = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, vop_cred); AFS_GUNLOCK(); return error; } @@ -1185,53 +1577,167 @@ extern int prtactive; int afs_vop_inactive(ap) - struct vop_inactive_args /* { + struct VOPPROT(inactive_args) /* { * struct vnode *a_vp; * struct proc *a_p; * } */ *ap; { register struct vnode *vp = ap->a_vp; - - if (prtactive && vp->v_usecount != 0) + struct vcache *tvc = VTOAFS(vp); +#ifndef AFS_DARWIN80_ENV + if (prtactive && vnode_isinuse(vp, 0) != 0) vprint("afs_vop_inactive(): pushing active", vp); - - AFS_GLOCK(); - afs_InactiveVCache(VTOAFS(vp), 0); /* decrs ref counts */ - AFS_GUNLOCK(); +#endif + if (tvc) { + AFS_GLOCK(); + afs_InactiveVCache(tvc, 0); /* decrs ref counts */ + AFS_GUNLOCK(); + } +#ifndef AFS_DARWIN80_ENV VOP_UNLOCK(vp, 0, ap->a_p); +#endif return 0; } int afs_vop_reclaim(ap) - struct vop_reclaim_args /* { + struct VOPPROT(reclaim_args) /* { * struct vnode *a_vp; * } */ *ap; { int error = 0; int sl; register struct vnode *vp = ap->a_vp; - int haveGlock = ISAFS_GLOCK(); struct vcache *tvc = VTOAFS(vp); + osi_Assert(!ISAFS_GLOCK()); cache_purge(vp); /* just in case... */ - if (!haveGlock) - AFS_GLOCK(); - error = afs_FlushVCache(VTOAFS(vp), &sl); /* toss our stuff from vnode */ - if (!haveGlock) - AFS_GUNLOCK(); + if (tvc) { + AFS_GLOCK(); + ObtainWriteLock(&afs_xvcache, 335); + error = afs_FlushVCache(tvc, &sl); /* toss our stuff from vnode */ + if (tvc->states & (CVInit | CDeadVnode)) { + tvc->states &= ~(CVInit | CDeadVnode); + afs_osi_Wakeup(&tvc->states); + } + ReleaseWriteLock(&afs_xvcache); + AFS_GUNLOCK(); + if (!error && vnode_fsnode(vp)) + panic("afs_reclaim: vnode not cleaned"); + if (!error && (tvc->v != NULL)) + panic("afs_reclaim: vcache not cleaned"); + } + return error; +} - if (!error && vp->v_data) - panic("afs_reclaim: vnode not cleaned"); - if (!error && (tvc->v != NULL)) - panic("afs_reclaim: vcache not cleaned"); +/* + * Return POSIX pathconf information applicable to ufs filesystems. + */ +afs_vop_pathconf(ap) + struct VOPPROT(pathconf_args) /* { + * struct vnode *a_vp; + * int a_name; + * int *a_retval; + * } */ *ap; +{ + AFS_STATCNT(afs_cntl); + switch (ap->a_name) { + case _PC_LINK_MAX: + *ap->a_retval = LINK_MAX; + break; + case _PC_NAME_MAX: + *ap->a_retval = NAME_MAX; + break; + case _PC_PATH_MAX: + *ap->a_retval = PATH_MAX; + break; + case _PC_CHOWN_RESTRICTED: + *ap->a_retval = 1; + break; + case _PC_NO_TRUNC: + *ap->a_retval = 1; + break; + case _PC_PIPE_BUF: + return EINVAL; + break; +#if defined(AFS_DARWIN70_ENV) + case _PC_NAME_CHARS_MAX: + *ap->a_retval = NAME_MAX; + break; + case _PC_CASE_SENSITIVE: + *ap->a_retval = 1; + break; + case _PC_CASE_PRESERVING: + *ap->a_retval = 1; + break; +#endif /* defined(AFS_DARWIN70_ENV) */ + default: + return EINVAL; + } + return 0; +} +/* + * Advisory record locking support (fcntl() POSIX style) + */ +int +afs_vop_advlock(ap) + struct VOPPROT(advlock_args) /* { + * struct vnode *a_vp; + * caddr_t a_id; + * int a_op; + * struct flock *a_fl; + * int a_flags; + * } */ *ap; +{ + int error; + struct ucred *tcr; +#ifdef AFS_DARWIN80_ENV + tcr=vop_cred; +#else + struct proc *p = current_proc(); + struct ucred cr; + pcred_readlock(p); + cr = *p->p_cred->pc_ucred; + pcred_unlock(p); + tcr=&cr; +#endif + AFS_GLOCK(); + error = + afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, tcr, (int)ap->a_id); + AFS_GUNLOCK(); return error; } +int +afs_vop_blktooff(ap) + struct VOPPROT(blktooff_args) /* { + * struct vnode *a_vp; + * daddr_t a_lblkno; + * off_t *a_offset; + * } */ *ap; +{ + *ap->a_offset = (off_t) (ap->a_lblkno * DEV_BSIZE); + return 0; +} + +int +afs_vop_offtoblk(ap) + struct VOPPROT(offtoblk_args) /* { + * struct vnode *a_vp; + * off_t a_offset; + * daddr_t *a_lblkno; + * } */ *ap; +{ + *ap->a_lblkno = (daddr_t) (ap->a_offset / DEV_BSIZE); + + return (0); +} + +#ifndef AFS_DARWIN80_ENV int afs_vop_lock(ap) - struct vop_lock_args /* { + struct VOPPROT(lock_args) /* { * struct vnode *a_vp; * } */ *ap; { @@ -1246,7 +1752,7 @@ afs_vop_lock(ap) int afs_vop_unlock(ap) - struct vop_unlock_args /* { + struct VOPPROT(unlock_args) /* { * struct vnode *a_vp; * } */ *ap; { @@ -1259,9 +1765,36 @@ afs_vop_unlock(ap) } +int +afs_vop_truncate(ap) + struct VOPPROT(truncate_args) /* { + * struct vnode *a_vp; + * off_t a_length; + * int a_flags; + * struct ucred *a_cred; + * struct proc *a_p; + * } */ *ap; +{ + printf("stray afs_vop_truncate\n"); + return EOPNOTSUPP; +} + +int +afs_vop_update(ap) + struct VOPPROT(update_args) /* { + * struct vnode *a_vp; + * struct timeval *a_access; + * struct timeval *a_modify; + * int a_waitfor; + * } */ *ap; +{ + printf("stray afs_vop_update\n"); + return EOPNOTSUPP; +} + int afs_vop_bmap(ap) - struct vop_bmap_args /* { + struct VOPPROT(bmap_args) /* { * struct vnode *a_vp; * daddr_t a_bn; * struct vnode **a_vpp; @@ -1289,7 +1822,7 @@ afs_vop_bmap(ap) int afs_vop_strategy(ap) - struct vop_strategy_args /* { + struct VOPPROT(strategy_args) /* { * struct buf *a_bp; * } */ *ap; { @@ -1302,7 +1835,7 @@ afs_vop_strategy(ap) int afs_vop_print(ap) - struct vop_print_args /* { + struct VOPPROT(print_args) /* { * struct vnode *a_vp; * } */ *ap; { @@ -1336,7 +1869,7 @@ afs_vop_print(ap) int afs_vop_islocked(ap) - struct vop_islocked_args /* { + struct VOPPROT(islocked_args) /* { * struct vnode *a_vp; * } */ *ap; { @@ -1344,134 +1877,9 @@ afs_vop_islocked(ap) return lockstatus(&vc->rwlock); } -/* - * Return POSIX pathconf information applicable to ufs filesystems. - */ -afs_vop_pathconf(ap) - struct vop_pathconf_args /* { - * struct vnode *a_vp; - * int a_name; - * int *a_retval; - * } */ *ap; -{ - AFS_STATCNT(afs_cntl); - switch (ap->a_name) { - case _PC_LINK_MAX: - *ap->a_retval = LINK_MAX; - break; - case _PC_NAME_MAX: - *ap->a_retval = NAME_MAX; - break; - case _PC_PATH_MAX: - *ap->a_retval = PATH_MAX; - break; - case _PC_CHOWN_RESTRICTED: - *ap->a_retval = 1; - break; - case _PC_NO_TRUNC: - *ap->a_retval = 1; - break; - case _PC_PIPE_BUF: - return EINVAL; - break; -#if defined(AFS_DARWIN70_ENV) - case _PC_NAME_CHARS_MAX: - *ap->a_retval = NAME_MAX; - break; - case _PC_CASE_SENSITIVE: - *ap->a_retval = 1; - break; - case _PC_CASE_PRESERVING: - *ap->a_retval = 1; - break; -#endif /* defined(AFS_DARWIN70_ENV) */ - default: - return EINVAL; - } - return 0; -} - -/* - * Advisory record locking support (fcntl() POSIX style) - */ -int -afs_vop_advlock(ap) - struct vop_advlock_args /* { - * struct vnode *a_vp; - * caddr_t a_id; - * int a_op; - * struct flock *a_fl; - * int a_flags; - * } */ *ap; -{ - int error; - struct proc *p = current_proc(); - struct ucred cr; - pcred_readlock(p); - cr = *p->p_cred->pc_ucred; - pcred_unlock(p); - AFS_GLOCK(); - error = - afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, &cr, (int)ap->a_id); - AFS_GUNLOCK(); - return error; -} - -int -afs_vop_truncate(ap) - struct vop_truncate_args /* { - * struct vnode *a_vp; - * off_t a_length; - * int a_flags; - * struct ucred *a_cred; - * struct proc *a_p; - * } */ *ap; -{ - printf("stray afs_vop_truncate\n"); - return EOPNOTSUPP; -} - -int -afs_vop_update(ap) - struct vop_update_args /* { - * struct vnode *a_vp; - * struct timeval *a_access; - * struct timeval *a_modify; - * int a_waitfor; - * } */ *ap; -{ - printf("stray afs_vop_update\n"); - return EOPNOTSUPP; -} - -int -afs_vop_blktooff(ap) - struct vop_blktooff_args /* { - * struct vnode *a_vp; - * daddr_t a_lblkno; - * off_t *a_offset; - * } */ *ap; -{ - *ap->a_offset = (off_t) (ap->a_lblkno * DEV_BSIZE); - return 0; -} - -int -afs_vop_offtoblk(ap) - struct vop_offtoblk_args /* { - * struct vnode *a_vp; - * off_t a_offset; - * daddr_t *a_lblkno; - * } */ *ap; -{ - *ap->a_lblkno = (daddr_t) (ap->a_offset / DEV_BSIZE); - - return (0); -} - int afs_vop_cmap(ap) - struct vop_cmap_args /* { + struct VOPPROT(cmap_args) /* { * struct vnode *a_vp; * off_t a_foffset; * size_t a_size; @@ -1484,13 +1892,127 @@ afs_vop_cmap(ap) *ap->a_run = MAX(ap->a_size, AFS_CHUNKSIZE(ap->a_foffset)); return 0; } +#endif -void -afs_darwin_getnewvnode(struct vcache *tvc) +int +afs_darwin_getnewvnode(struct vcache *avc) { - while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &tvc->v)) { +#ifdef AFS_DARWIN80_ENV + vnode_t vp; + int error, dead; + struct vnode_fsparam par; + + memset(&par, 0, sizeof(struct vnode_fsparam)); +#if 0 + AFS_GLOCK(); + ObtainWriteLock(&avc->lock,342); + if (avc->states & CStatd) { + par.vnfs_vtype = avc->m.Type; + par.vnfs_vops = afs_vnodeop_p; + par.vnfs_filesize = avc->m.Length; + if (!ac->cnp) + par.vnfs_flags = VNFS_NOCACHE; + dead = 0; + } else { + par.vnfs_vtype = VNON; + par.vnfs_vops = afs_dead_vnodeop_p; + par.vnfs_flags = VNFS_NOCACHE|VNFS_CANTCACHE; + dead = 1; + } + ReleaseWriteLock(&avc->lock); + AFS_GUNLOCK(); + par.vnfs_dvp = ac->dvp; + par.vnfs_cnp = ac->cnp; + par.vnfs_markroot = ac->markroot; +#else + par.vnfs_vtype = VNON; + par.vnfs_vops = afs_dead_vnodeop_p; + par.vnfs_flags = VNFS_NOCACHE|VNFS_CANTCACHE; +#endif + par.vnfs_mp = afs_globalVFS; + par.vnfs_fsnode = avc; + + error = vnode_create(VNCREATE_FLAVOR, VCREATESIZE, &par, &vp); + if (!error) { + vnode_addfsref(vp); + vnode_ref(vp); + avc->v = vp; +#if 0 + if (dead) { + vnode_recycle(vp); /* terminate as soon as iocount drops */ + avc->states |= CDeadVnode; + } else if (!ac->markroot && !ac->cnp) { + /* the caller doesn't know anything about this vnode. if markroot + should have been set and wasn't, bad things may happen, so encourage + it to recycle */ + vnode_recycle(vp); + } +#else + vnode_recycle(vp); /* terminate as soon as iocount drops */ + avc->states |= CDeadVnode; +#endif + } + return error; +#else + while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &avc->v)) { /* no vnodes available, force an alloc (limits be damned)! */ printf("failed to get vnode\n"); } - tvc->v->v_data = (void *)tvc; + avc->v->v_data = (void *)avc; + return 0; +#endif } +#ifdef AFS_DARWIN80_ENV +/* if this fails, then tvc has been unrefed and may have been freed. + Don't touch! */ +int +afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, struct componentname *cnp, int isroot) { + vnode_t ovp = AFSTOV(avc); + vnode_t nvp; + int error; + struct vnode_fsparam par; + AFS_GLOCK(); + ObtainWriteLock(&avc->lock,325); + if (!(avc->states & CDeadVnode) && vnode_vtype(ovp) != VNON) { + ReleaseWriteLock(&avc->lock); + AFS_GUNLOCK(); +#if 0 /* unsupported */ + if (dvp && cnp) + vnode_update_identity(ovp, dvp, cnp->cn_nameptr, cnp->cn_namelen, + cnp->cn_hash, + VNODE_UPDATE_PARENT|VNODE_UPDATE_NAME); +#endif + vnode_rele(ovp); + return 0; + } + if ((avc->states & CDeadVnode) && vnode_vtype(ovp) != VNON) + panic("vcache %p should not be CDeadVnode", avc); + AFS_GUNLOCK(); + memset(&par, 0, sizeof(struct vnode_fsparam)); + par.vnfs_mp = afs_globalVFS; + par.vnfs_vtype = avc->m.Type; + par.vnfs_vops = afs_vnodeop_p; + par.vnfs_filesize = avc->m.Length; + par.vnfs_fsnode = avc; + par.vnfs_dvp = dvp; + par.vnfs_cnp = cnp; + if (isroot) + par.vnfs_markroot = 1; + error = vnode_create(VNCREATE_FLAVOR, VCREATESIZE, &par, &nvp); + if (!error) { + vnode_addfsref(nvp); + avc->v = nvp; + avc->states &=~ CDeadVnode; + vnode_clearfsnode(ovp); + vnode_removefsref(ovp); + } + AFS_GLOCK(); + ReleaseWriteLock(&avc->lock); + if (!error) + afs_osi_Wakeup(&avc->states); + AFS_GUNLOCK(); + vnode_put(ovp); + vnode_rele(ovp); + return error; +} +#endif diff --git a/src/afs/VNOPS/afs_vnop_attrs.c b/src/afs/VNOPS/afs_vnop_attrs.c index 8c8a72241..c1812334d 100644 --- a/src/afs/VNOPS/afs_vnop_attrs.c +++ b/src/afs/VNOPS/afs_vnop_attrs.c @@ -93,6 +93,8 @@ afs_CopyOutAttrs(register struct vcache *avc, register struct vattr *attrs) attrs->va_fsid = avc->v.v_vfsp->vfs_fsid.val[0]; #elif defined(AFS_OSF_ENV) attrs->va_fsid = avc->v.v_mount->m_stat.f_fsid.val[0]; +#elif defined(AFS_DARWIN80_ENV) + VATTR_RETURN(attrs, va_fsid, vfs_statfs(vnode_mount(AFSTOV(avc)))->f_fsid.val[0]); #elif defined(AFS_DARWIN70_ENV) attrs->va_fsid = avc->v->v_mount->mnt_stat.f_fsid.val[0]; #else /* ! AFS_DARWIN70_ENV */ @@ -156,26 +158,19 @@ afs_CopyOutAttrs(register struct vcache *avc, register struct vattr *attrs) * Below return 0 (and not 1) blocks if the file is zero length. This conforms * better with the other filesystems that do return 0. */ -#if !defined(AFS_OSF_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV) -#if !defined(AFS_HPUX_ENV) -#ifdef AFS_SUN5_ENV - attrs->va_nblocks = - (attrs->va_size ? ((attrs->va_size + 1023) >> 10) << 1 : 0); +#ifdef AFS_HPUX_ENV + attrs->va_blocks = (attrs->va_size ? ((attrs->va_size + 1023) >> 10) : 0); #elif defined(AFS_SGI_ENV) attrs->va_blocks = BTOBB(attrs->va_size); -#else - attrs->va_blocks = - (attrs->va_size ? ((attrs->va_size + 1023) >> 10) << 1 : 0); -#endif -#else /* !defined(AFS_HPUX_ENV) */ - attrs->va_blocks = (attrs->va_size ? ((attrs->va_size + 1023) >> 10) : 0); -#endif /* !defined(AFS_HPUX_ENV) */ -#else /* ! AFS_OSF_ENV && !AFS_DARWIN_ENV && !AFS_XBSD_ENV */ +#elif defined(AFS_XBSD_ENV) || defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) attrs->va_bytes = (attrs->va_size ? (attrs->va_size + 1023) : 1024); #ifdef va_bytes_rsv attrs->va_bytes_rsv = -1; #endif -#endif /* ! AFS_OSF_ENV && !AFS_DARWIN_ENV && !AFS_XBSD_ENV */ +#else + attrs->va_blocks = + (attrs->va_size ? ((attrs->va_size + 1023) >> 10) << 1 : 0); +#endif return 0; } @@ -225,7 +220,7 @@ afs_getattr(OSI_VC_DECL(avc), struct vattr *attrs, struct AFS_UCRED *acred) return code; } #endif -#if defined(AFS_DARWIN_ENV) +#if defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN80_ENV) if (avc->states & CUBCinit) { code = afs_CopyOutAttrs(avc, attrs); return code; @@ -297,9 +292,19 @@ afs_getattr(OSI_VC_DECL(avc), struct vattr *attrs, struct AFS_UCRED *acred) attrs->va_nodeid = ip->i_ino; /* VTOI()? */ } #else - if (AFSTOV(avc)->v_flag & VROOT) { + if ( +#ifdef AFS_DARWIN_ENV + vnode_isvroot(AFSTOV(avc)) +#else + AFSTOV(avc)->v_flag & VROOT +#endif + ) { struct vnode *vp = AFSTOV(avc); +#ifdef AFS_DARWIN80_ENV + /* XXX vp = vnode_mount(vp)->mnt_vnodecovered; */ + vp = 0; +#else vp = vp->v_vfsp->vfs_vnodecovered; if (vp) { /* Ignore weird failures */ #ifdef AFS_SGI62_ENV @@ -312,6 +317,7 @@ afs_getattr(OSI_VC_DECL(avc), struct vattr *attrs, struct AFS_UCRED *acred) attrs->va_nodeid = ip->i_number; #endif } +#endif } #endif /* AFS_LINUX22_ENV */ } @@ -333,7 +339,9 @@ afs_VAttrToAS(register struct vcache *avc, register struct vattr *av, register int mask; mask = 0; AFS_STATCNT(afs_VAttrToAS); -#if defined(AFS_AIX_ENV) +#if defined(AFS_DARWIN80_ENV) + if (VATTR_IS_ACTIVE(av, va_mode)) { +#elif defined(AFS_AIX_ENV) /* Boy, was this machine dependent bogosity hard to swallow????.... */ if (av->va_mode != -1) { #elif defined(AFS_LINUX22_ENV) @@ -353,7 +361,9 @@ afs_VAttrToAS(register struct vcache *avc, register struct vattr *av, ReleaseWriteLock(&avc->lock); } } -#if defined(AFS_LINUX22_ENV) +#if defined(AFS_DARWIN80_ENV) + if (VATTR_IS_ACTIVE(av, va_gid)) { +#elif defined(AFS_LINUX22_ENV) if (av->va_mask & ATTR_GID) { #elif defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) if (av->va_mask & AT_GID) { @@ -371,7 +381,9 @@ afs_VAttrToAS(register struct vcache *avc, register struct vattr *av, mask |= AFS_SETGROUP; as->Group = av->va_gid; } -#if defined(AFS_LINUX22_ENV) +#if defined(AFS_DARWIN80_ENV) + if (VATTR_IS_ACTIVE(av, va_uid)) { +#elif defined(AFS_LINUX22_ENV) if (av->va_mask & ATTR_UID) { #elif defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) if (av->va_mask & AT_UID) { @@ -389,7 +401,9 @@ afs_VAttrToAS(register struct vcache *avc, register struct vattr *av, mask |= AFS_SETOWNER; as->Owner = av->va_uid; } -#if defined(AFS_LINUX22_ENV) +#if defined(AFS_DARWIN80_ENV) + if (VATTR_IS_ACTIVE(av, va_modify_time)) { +#elif defined(AFS_LINUX22_ENV) if (av->va_mask & ATTR_MTIME) { #elif defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) if (av->va_mask & AT_MTIME) { @@ -466,7 +480,9 @@ afs_setattr(OSI_VC_DECL(avc), register struct vattr *attrs, * chmod) give it a shot; if it fails, we'll discard the status * info. */ -#if defined(AFS_LINUX22_ENV) +#if defined(AFS_DARWIN80_ENV) + if (VATTR_IS_ACTIVE(attrs, va_data_size)) { +#elif defined(AFS_LINUX22_ENV) if (attrs->va_mask & ATTR_SIZE) { #elif defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) if (attrs->va_mask & AT_SIZE) { @@ -497,7 +513,9 @@ afs_setattr(OSI_VC_DECL(avc), register struct vattr *attrs, #if defined(AFS_SGI_ENV) AFS_RWLOCK((vnode_t *) avc, VRWLOCK_WRITE); #endif -#if defined(AFS_LINUX22_ENV) +#if defined(AFS_DARWIN80_ENV) + if (VATTR_IS_ACTIVE(attrs, va_data_size)) { +#elif defined(AFS_LINUX22_ENV) if (attrs->va_mask & ATTR_SIZE) { #elif defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) if (attrs->va_mask & AT_SIZE) { diff --git a/src/afs/VNOPS/afs_vnop_create.c b/src/afs/VNOPS/afs_vnop_create.c index c8fa7fe7c..71ec4a935 100644 --- a/src/afs/VNOPS/afs_vnop_create.c +++ b/src/afs/VNOPS/afs_vnop_create.c @@ -179,7 +179,9 @@ afs_create(OSI_VC_DECL(adp), char *aname, struct vattr *attrs, code = EACCES; goto done; } -#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) +#if defined(AFS_DARWIN80_ENV) + if ((amode & VWRITE) || VATTR_IS_ACTIVE(attrs, va_data_size)) +#elif defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) if ((amode & VWRITE) || (attrs->va_mask & AT_SIZE)) #else if ((amode & VWRITE) || len != 0xffffffff) @@ -196,7 +198,9 @@ afs_create(OSI_VC_DECL(adp), char *aname, struct vattr *attrs, goto done; } } -#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) +#if defined(AFS_DARWIN80_ENV) + if (VATTR_IS_ACTIVE(attrs, va_data_size)) +#elif defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) if (attrs->va_mask & AT_SIZE) #else if (len != 0xffffffff) @@ -208,7 +212,11 @@ afs_create(OSI_VC_DECL(adp), char *aname, struct vattr *attrs, goto done; } /* do a truncate */ -#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) +#if defined(AFS_DARWIN80_ENV) + VATTR_INIT(attrs); + VATTR_SET_SUPPORTED(attrs, va_data_size); + VATTR_SET_ACTIVE(attrs, va_data_size); +#elif defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) attrs->va_mask = AT_SIZE; #else VATTR_NULL(attrs); diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index be887e771..057dc4373 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -249,7 +249,7 @@ afs_InitFakeStat(struct afs_fakestat_state *state) * * Only issues RPCs if canblock is non-zero. */ -int +static int afs_EvalFakeStat_int(struct vcache **avcp, struct afs_fakestat_state *state, struct vrequest *areq, int canblock) { @@ -305,6 +305,14 @@ afs_EvalFakeStat_int(struct vcache **avcp, struct afs_fakestat_state *state, code = canblock ? ENOENT : 0; goto done; } +#ifdef AFS_DARWIN80_ENV + root_vp->m.Type = VDIR; + AFS_GUNLOCK(); + code = afs_darwin_finalizevnode(root_vp, NULL, NULL, 0); + AFS_GLOCK(); + if (code) goto done; + vnode_ref(AFSTOV(root_vp)); +#endif if (tvolp) { /* Is this always kosher? Perhaps we should instead use * NBObtainWriteLock to avoid potential deadlock. @@ -563,6 +571,9 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) int flagIndex = 0; /* First file with bulk fetch flag set */ int inlinebulk = 0; /* Did we use InlineBulk RPC or not? */ XSTATS_DECLS; +#ifdef AFS_DARWIN80_ENV + panic("bulkstatus doesn't work on AFS_DARWIN80_ENV. don't call it"); +#endif /* first compute some basic parameters. We dont want to prefetch more * than a fraction of the cache in any given call, and we want to preserve * a portion of the LRU queue in any event, so as to avoid thrashing @@ -708,6 +719,15 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) if (!tvcp) goto done; /* can't happen at present, more's the pity */ +#ifdef AFS_DARWIN80_ENV + if (tvcp->states & CVInit) { + /* XXX don't have status yet, so creating the vnode is + not yet useful. we would get CDeadVnode set, and the + upcoming PutVCache will cause the vcache to be flushed & + freed, which in turn means the bulkstatus results won't + be used */ + } +#endif /* WARNING: afs_DoBulkStat uses the Length field to store a * sequence number for each bulk status request. Under no * circumstances should afs_DoBulkStat store a sequence number @@ -869,6 +889,9 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) ReleaseReadLock(&afs_xvcache); /* could be read lock */ if (retry) goto reskip; +#ifdef AFS_DARWIN80_ENV + vnode_get(AFSTOV(lruvcp)); +#endif /* otherwise, merge in the info. We have to be quite careful here, * since we need to ensure that we don't merge old info over newer @@ -1066,7 +1089,11 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) } /* was: (AFS_DEC_ENV) || defined(AFS_OSF30_ENV) || defined(AFS_NCR_ENV) */ +#ifdef AFS_DARWIN80_ENV +#define AFSDOBULK 0 +#else static int AFSDOBULK = 1; +#endif int #ifdef AFS_OSF_ENV @@ -1169,7 +1196,7 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED *avcp = tvc; code = (tvc ? 0 : ENOENT); hit = 1; - if (tvc && !VREFCOUNT(tvc)) { + if (tvc && !VREFCOUNT_GT(tvc, 0)) { osi_Panic("TT1"); } if (code) { @@ -1202,10 +1229,13 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED ObtainReadLock(&afs_xvcache); osi_vnhold(adp, 0); ReleaseReadLock(&afs_xvcache); +#ifdef AFS_DARWIN80_ENV + vnode_get(AFSTOV(adp)); +#endif code = 0; *avcp = tvc = adp; hit = 1; - if (adp && !VREFCOUNT(adp)) { + if (adp && !VREFCOUNT_GT(adp, 0)) { osi_Panic("TT2"); } goto done; @@ -1489,7 +1519,7 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED } } *avcp = tvc; - if (tvc && !VREFCOUNT(tvc)) { + if (tvc && !VREFCOUNT_GT(tvc, 0)) { osi_Panic("TT3"); } code = 0; diff --git a/src/afs/VNOPS/afs_vnop_read.c b/src/afs/VNOPS/afs_vnop_read.c index 5efc7b43c..c3da3fa99 100644 --- a/src/afs/VNOPS/afs_vnop_read.c +++ b/src/afs/VNOPS/afs_vnop_read.c @@ -60,8 +60,13 @@ afs_MemRead(register struct vcache *avc, struct uio *auio, afs_int32 trimlen; struct dcache *tdc = 0; afs_int32 error, trybusy = 1; +#ifdef AFS_DARWIN80_ENV + uio_t tuiop = NULL; +#else struct uio tuio; + struct uio *tuiop = &tuio; struct iovec *tvec; +#endif afs_int32 code; struct vrequest treq; @@ -89,9 +94,11 @@ afs_MemRead(register struct vcache *avc, struct uio *auio, } #endif +#ifndef AFS_DARWIN80_ENV tvec = (struct iovec *)osi_AllocSmallSpace(sizeof(struct iovec)); - totalLength = auio->afsio_resid; - filePos = auio->afsio_offset; +#endif + totalLength = AFS_UIO_RESID(auio); + filePos = AFS_UIO_OFFSET(auio); afs_Trace4(afs_iclSetp, CM_TRACE_READ, ICL_TYPE_POINTER, avc, ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(filePos), ICL_TYPE_INT32, totalLength, ICL_TYPE_OFFSET, @@ -301,10 +308,15 @@ afs_MemRead(register struct vcache *avc, struct uio *auio, len = tlen; if (len > AFS_ZEROS) len = sizeof(afs_zeros); /* and in 0 buffer */ +#ifdef AFS_DARWIN80_ENV + trimlen = len; + tuiop = afsio_darwin_partialcopy(auio, trimlen); +#else afsio_copy(auio, &tuio, tvec); trimlen = len; afsio_trim(&tuio, trimlen); - AFS_UIOMOVE(afs_zeros, trimlen, UIO_READ, &tuio, code); +#endif + AFS_UIOMOVE(afs_zeros, trimlen, UIO_READ, tuiop, code); if (code) { error = code; break; @@ -313,12 +325,18 @@ afs_MemRead(register struct vcache *avc, struct uio *auio, /* get the data from the mem cache */ /* mung uio structure to be right for this transfer */ +#ifdef AFS_DARWIN80_ENV + trimlen = len; + tuiop = afsio_darwin_partialcopy(auio, trimlen); + uio_setoffset(tuiop, offset); +#else afsio_copy(auio, &tuio, tvec); trimlen = len; afsio_trim(&tuio, trimlen); tuio.afsio_offset = offset; +#endif - code = afs_MemReadUIO(tdc->f.inode, &tuio); + code = afs_MemReadUIO(tdc->f.inode, tuiop); if (code) { error = code; @@ -326,7 +344,7 @@ afs_MemRead(register struct vcache *avc, struct uio *auio, } } /* otherwise we've read some, fixup length, etc and continue with next seg */ - len = len - tuio.afsio_resid; /* compute amount really transferred */ + len = len - AFS_UIO_RESID(tuiop); /* compute amount really transferred */ trimlen = len; afsio_skip(auio, trimlen); /* update input uio structure */ totalLength -= len; @@ -359,7 +377,12 @@ afs_MemRead(register struct vcache *avc, struct uio *auio, } if (!noLock) ReleaseReadLock(&avc->lock); +#ifdef AFS_DARWIN80_ENV + if (tuiop) + uio_free(tuiop); +#else osi_FreeSmallSpace(tvec); +#endif error = afs_CheckCode(error, &treq, 10); return error; } @@ -448,8 +471,13 @@ afs_UFSRead(register struct vcache *avc, struct uio *auio, afs_int32 trimlen; struct dcache *tdc = 0; afs_int32 error; +#ifdef AFS_DARWIN80_ENV + uio_t tuiop=NULL; +#else struct uio tuio; + struct uio *tuiop = &tuio; struct iovec *tvec; +#endif struct osi_file *tfile; afs_int32 code; int trybusy = 1; @@ -483,9 +511,11 @@ afs_UFSRead(register struct vcache *avc, struct uio *auio, } #endif +#ifndef AFS_DARWIN80_ENV tvec = (struct iovec *)osi_AllocSmallSpace(sizeof(struct iovec)); - totalLength = auio->afsio_resid; - filePos = auio->afsio_offset; +#endif + totalLength = AFS_UIO_RESID(auio); + filePos = AFS_UIO_OFFSET(auio); afs_Trace4(afs_iclSetp, CM_TRACE_READ, ICL_TYPE_POINTER, avc, ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(filePos), ICL_TYPE_INT32, totalLength, ICL_TYPE_OFFSET, @@ -686,10 +716,15 @@ afs_UFSRead(register struct vcache *avc, struct uio *auio, len = tlen; if (len > AFS_ZEROS) len = sizeof(afs_zeros); /* and in 0 buffer */ +#ifdef AFS_DARWIN80_ENV + trimlen = len; + tuiop = afsio_darwin_partialcopy(auio, trimlen); +#else afsio_copy(auio, &tuio, tvec); trimlen = len; afsio_trim(&tuio, trimlen); - AFS_UIOMOVE(afs_zeros, trimlen, UIO_READ, &tuio, code); +#endif + AFS_UIOMOVE(afs_zeros, trimlen, UIO_READ, tuiop, code); if (code) { error = code; break; @@ -712,11 +747,18 @@ afs_UFSRead(register struct vcache *avc, struct uio *auio, #endif /* IHINT */ tfile = (struct osi_file *)osi_UFSOpen(tdc->f.inode); +#ifdef AFS_DARWIN80_ENV + trimlen = len; + tuiop = afsio_darwin_partialcopy(auio, trimlen); + uio_setoffset(tuiop, offset); +#else /* mung uio structure to be right for this transfer */ afsio_copy(auio, &tuio, tvec); trimlen = len; afsio_trim(&tuio, trimlen); tuio.afsio_offset = offset; +#endif + #if defined(AFS_AIX41_ENV) AFS_GUNLOCK(); code = @@ -790,6 +832,10 @@ afs_UFSRead(register struct vcache *avc, struct uio *auio, AFS_GUNLOCK(); code = osi_rdwr(tfile, &tuio, UIO_READ); AFS_GLOCK(); +#elif defined(AFS_DARWIN80_ENV) + AFS_GUNLOCK(); + code = VNOP_READ(tfile->vnode, tuiop, 0, afs_osi_ctxtp); + AFS_GLOCK(); #elif defined(AFS_DARWIN_ENV) AFS_GUNLOCK(); VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, current_proc()); @@ -826,7 +872,7 @@ afs_UFSRead(register struct vcache *avc, struct uio *auio, } } /* otherwise we've read some, fixup length, etc and continue with next seg */ - len = len - tuio.afsio_resid; /* compute amount really transferred */ + len = len - AFS_UIO_RESID(tuiop); /* compute amount really transferred */ trimlen = len; afsio_skip(auio, trimlen); /* update input uio structure */ totalLength -= len; @@ -854,7 +900,12 @@ afs_UFSRead(register struct vcache *avc, struct uio *auio, if (!noLock) ReleaseReadLock(&avc->lock); +#ifdef AFS_DARWIN80_ENV + if (tuiop) + uio_free(tuiop); +#else osi_FreeSmallSpace(tvec); +#endif error = afs_CheckCode(error, &treq, 13); return error; } diff --git a/src/afs/VNOPS/afs_vnop_readdir.c b/src/afs/VNOPS/afs_vnop_readdir.c index 2b385af4b..4168ca505 100644 --- a/src/afs/VNOPS/afs_vnop_readdir.c +++ b/src/afs/VNOPS/afs_vnop_readdir.c @@ -143,7 +143,12 @@ struct irix5_min_dirent { /* miniature dirent structure */ #else struct min_direct { /* miniature direct structure */ /* If struct direct changes, this must too */ -#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) +#if defined(AFS_DARWIN80_ENV) + ino_t d_fileno; + u_short d_reclen; + u_char d_type; + u_char d_namlen; +#elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) afs_uint32 d_fileno; u_short d_reclen; u_char d_type; @@ -627,7 +632,7 @@ afs_readdir(OSI_VC_ARG(avc), auio, acred) #endif #ifndef AFS_64BIT_CLIENT if (AfsLargeFileUio(auio) /* file is large than 2 GB */ - ||AfsLargeFileSize(auio->uio_offset, auio->uio_resid)) + ||AfsLargeFileSize(AFS_UIO_OFFSET(auio), AFS_UIO_RESID(auio))) return EFBIG; #endif @@ -712,7 +717,7 @@ afs_readdir(OSI_VC_ARG(avc), auio, acred) auio->uio_fpflags = 0; #endif while (code == 0) { - origOffset = auio->afsio_offset; + origOffset = AFS_UIO_OFFSET(auio); /* scan for the next interesting entry scan for in-use blob otherwise up point at * this blob note that ode, if non-zero, also represents a held dir page */ if (!(us = BlobScan(tdc, (origOffset >> 5))) @@ -724,7 +729,7 @@ afs_readdir(OSI_VC_ARG(avc), auio, acred) sdirEntry->d_fileno = (avc->fid.Fid.Volume << 16) + ntohl(ode->fid.vnode); FIXUPSTUPIDINODE(sdirEntry->d_fileno); - sdirEntry->d_reclen = rlen = auio->afsio_resid; + sdirEntry->d_reclen = rlen = AFS_UIO_RESID(auio); sdirEntry->d_namlen = o_slen; #if defined(AFS_SUN5_ENV) || defined(AFS_AIX32_ENV) || defined(AFS_HPUX100_ENV) sdirEntry->d_off = origOffset; @@ -754,11 +759,11 @@ afs_readdir(OSI_VC_ARG(avc), auio, acred) #if defined(AFS_SUN5_ENV) len, origOffset); #else - auio->afsio_resid, origOffset); + AFS_UIO_RESID(auio), origOffset); #endif #endif /* AFS_HPUX_ENV */ #if !defined(AFS_SUN5_ENV) - auio->afsio_resid = 0; + AFS_UIO_SETRESID(auio, 0); #endif } else { /* nothin to hand over */ @@ -782,9 +787,9 @@ afs_readdir(OSI_VC_ARG(avc), auio, acred) #ifdef AFS_SGI53_ENV dirsiz = use64BitDirent ? DIRENTSIZE(n_slen) : IRIX5_DIRENTSIZE(n_slen); - if (dirsiz >= (auio->afsio_resid - len)) { + if (dirsiz >= (AFS_UIO_RESID(auio) - len)) { #else - if (DIRSIZ_LEN(n_slen) >= (auio->afsio_resid - len)) { + if (DIRSIZ_LEN(n_slen) >= (AFS_UIO_RESID(auio) - len)) { #endif /* AFS_SGI53_ENV */ /* No can do no more now; ya know... at this time */ DRelease((struct buffer *)nde, 0); /* can't use this one. */ @@ -793,7 +798,7 @@ afs_readdir(OSI_VC_ARG(avc), auio, acred) sdirEntry->d_fileno = (avc->fid.Fid.Volume << 16) + ntohl(ode->fid.vnode); FIXUPSTUPIDINODE(sdirEntry->d_fileno); - sdirEntry->d_reclen = rlen = auio->afsio_resid; + sdirEntry->d_reclen = rlen = AFS_UIO_RESID(auio); sdirEntry->d_namlen = o_slen; #if defined(AFS_SUN5_ENV) || defined(AFS_AIX32_ENV) || defined(AFS_HPUX100_ENV) sdirEntry->d_off = origOffset; @@ -821,12 +826,12 @@ afs_readdir(OSI_VC_ARG(avc), auio, acred) #else /* AFS_HPUX_ENV */ code = afs_readdir_move(ode, avc, auio, o_slen, - auio->afsio_resid, origOffset); + AFS_UIO_RESID(auio), origOffset); #endif /* AFS_HPUX_ENV */ /* this next line used to be AFSVFS40 or AIX 3.1, but is * really generic */ - auio->afsio_offset = origOffset; - auio->afsio_resid = 0; + AFS_UIO_SETOFFSET(auio, origOffset); + AFS_UIO_SETRESID(auio, 0); } else { /* trouble, can't give anything to the user! */ /* even though he has given us a buffer, * even though we have something to give us, @@ -887,8 +892,7 @@ afs_readdir(OSI_VC_ARG(avc), auio, acred) if (ode) DRelease((struct buffer *)ode, 0); ode = nde; - auio->afsio_offset = - (afs_int32) ((us + afs_dir_NameBlobs(nde->name)) << 5); + AFS_UIO_SETOFFSET(auio, (afs_int32) ((us + afs_dir_NameBlobs(nde->name)) << 5)); } if (ode) DRelease((struct buffer *)ode, 0); @@ -1002,7 +1006,7 @@ afs1_readdir(avc, auio, acred) auio->uio_fpflags = 0; #endif while (code == 0) { - origOffset = auio->afsio_offset; + origOffset = AFS_UIO_OFFSET(auio); /* scan for the next interesting entry scan for in-use blob otherwise up point at * this blob note that ode, if non-zero, also represents a held dir page */ @@ -1015,7 +1019,7 @@ afs1_readdir(avc, auio, acred) sdirEntry->d_fileno = (avc->fid.Fid.Volume << 16) + ntohl(ode->fid.vnode); FIXUPSTUPIDINODE(sdirEntry->d_fileno); - sdirEntry->d_reclen = rlen = auio->afsio_resid; + sdirEntry->d_reclen = rlen = AFS_UIO_RESID(auio); sdirEntry->d_namlen = o_slen; sdirEntry->d_off = origOffset; AFS_UIOMOVE((char *)sdirEntry, sizeof(*sdirEntry), UIO_READ, @@ -1042,9 +1046,9 @@ afs1_readdir(avc, auio, acred) #else code = afs_readdir_move(ode, avc, auio, o_slen, - auio->afsio_resid, origOffset); + AFS_UIO_RESID(auio), origOffset); #endif /* AFS_HPUX_ENV */ - auio->afsio_resid = 0; + AFS_UIO_SETRESID(auio, 0); } else { /* nothin to hand over */ } @@ -1064,7 +1068,7 @@ afs1_readdir(avc, auio, acred) #else n_slen = strlen(nde->name); #endif - if (NDIRSIZ_LEN(n_slen) >= (auio->afsio_resid - len)) { + if (NDIRSIZ_LEN(n_slen) >= (AFS_UIO_RESID(auio) - len)) { /* No can do no more now; ya know... at this time */ DRelease(nde, 0); /* can't use this one. */ if (len) { @@ -1072,7 +1076,7 @@ afs1_readdir(avc, auio, acred) sdirEntry->d_fileno = (avc->fid.Fid.Volume << 16) + ntohl(ode->fid.vnode); FIXUPSTUPIDINODE(sdirEntry->d_fileno); - sdirEntry->d_reclen = rlen = auio->afsio_resid; + sdirEntry->d_reclen = rlen = AFS_UIO_RESID(auio); sdirEntry->d_namlen = o_slen; sdirEntry->d_off = origOffset; AFS_UIOMOVE((char *)sdirEntry, sizeof(*sdirEntry), UIO_READ, @@ -1098,11 +1102,11 @@ afs1_readdir(avc, auio, acred) #else code = afs_readdir_move(ode, avc, auio, o_slen, - auio->afsio_resid, origOffset); + AFS_UIO_RESID(auio), origOffset); #endif /* AFS_HPUX_ENV */ /* this next line used to be AFSVFS40 or AIX 3.1, but is really generic */ - auio->afsio_offset = origOffset; - auio->afsio_resid = 0; + AFS_UIO_SETOFFSET(auio, origOffset); + AFS_UIO_SETRESID(auio, 0); } else { /* trouble, can't give anything to the user! */ /* even though he has given us a buffer, * even though we have something to give us, @@ -1155,7 +1159,7 @@ afs1_readdir(avc, auio, acred) if (ode) DRelease(ode, 0); ode = nde; - auio->afsio_offset = ((us + afs_dir_NameBlobs(nde->name)) << 5); + AFS_UIO_OFFSET(auio) = ((us + afs_dir_NameBlobs(nde->name)) << 5); } if (ode) DRelease(ode, 0); diff --git a/src/afs/VNOPS/afs_vnop_remove.c b/src/afs/VNOPS/afs_vnop_remove.c index 7dd8a5d87..5ea337ba7 100644 --- a/src/afs/VNOPS/afs_vnop_remove.c +++ b/src/afs/VNOPS/afs_vnop_remove.c @@ -362,20 +362,23 @@ afs_remove(OSI_VC_ARG(adp), aname, acred) osi_dnlc_remove(adp, aname, tvc); Tadp1 = adp; +#ifndef AFS_DARWIN80_ENV Tadpr = VREFCOUNT(adp); +#endif Ttvc = tvc; Tnam = aname; Tnam1 = 0; if (tvc) +#ifndef AFS_DARWIN80_ENV Ttvcr = VREFCOUNT(tvc); +#endif #ifdef AFS_AIX_ENV - if (tvc && (VREFCOUNT(tvc) > 2) && tvc->opens > 0 - && !(tvc->states & CUnlinked)) + if (tvc && VREFCOUNT_GT(tvc, 2) && tvc->opens > 0 + && !(tvc->states & CUnlinked)) { #else - if (tvc && (VREFCOUNT(tvc) > 1) && tvc->opens > 0 - && !(tvc->states & CUnlinked)) + if (tvc && VREFCOUNT_GT(tvc, 1) && tvc->opens > 0 + && !(tvc->states & CUnlinked)) { #endif - { char *unlname = afs_newname(); ReleaseWriteLock(&adp->lock); @@ -401,6 +404,7 @@ afs_remove(OSI_VC_ARG(adp), aname, acred) code = afsremove(adp, tdc, tvc, aname, acred, &treq); } afs_PutFakeStat(&fakestate); + osi_Assert(!WriteLocked(&adp->lock) || !(adp->lock.pid_writer != MyPidxx)); return code; } @@ -436,7 +440,7 @@ afs_remunlink(register struct vcache *avc, register int doit) cred = avc->uncred; avc->uncred = NULL; -#ifdef AFS_DARWIN_ENV +#if defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN80_ENV) VREF(AFSTOV(avc)); #else VN_HOLD(AFSTOV(avc)); diff --git a/src/afs/VNOPS/afs_vnop_strategy.c b/src/afs/VNOPS/afs_vnop_strategy.c index dc3dde637..766c2da23 100644 --- a/src/afs/VNOPS/afs_vnop_strategy.c +++ b/src/afs/VNOPS/afs_vnop_strategy.c @@ -18,7 +18,7 @@ RCSID ("$Header$"); -#if !defined(AFS_HPUX_ENV) && !defined(AFS_SGI_ENV) && !defined(AFS_LINUX20_ENV) +#if !defined(AFS_HPUX_ENV) && !defined(AFS_SGI_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN80_ENV) #include "afs/sysincludes.h" /* Standard vendor system headers */ #include "afsincludes.h" /* Afs-based standard headers */ @@ -40,6 +40,8 @@ afs_ustrategy(abp) { register afs_int32 code; struct uio tuio; + struct uio *tuiop = &tuio; + struct iovec tiovec[1]; register struct vcache *tvc = VTOAFS(abp->b_vp); register afs_int32 len = abp->b_bcount; #if !defined(AFS_SUN5_ENV) && !defined(AFS_OSF_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV) @@ -49,7 +51,6 @@ afs_ustrategy(abp) struct AFS_UCRED *credp = u.u_cred; #endif #endif - struct iovec tiovec[1]; AFS_STATCNT(afs_ustrategy); #ifdef AFS_AIX41_ENV diff --git a/src/afs/VNOPS/afs_vnop_write.c b/src/afs/VNOPS/afs_vnop_write.c index 4a7a4b3cd..ffcec3389 100644 --- a/src/afs/VNOPS/afs_vnop_write.c +++ b/src/afs/VNOPS/afs_vnop_write.c @@ -105,8 +105,13 @@ afs_MemWrite(register struct vcache *avc, struct uio *auio, int aio, volatile #endif afs_int32 error; +#ifdef AFS_DARWIN80_ENV + uio_t tuiop; +#else struct uio tuio; + struct uio *tuiop = &tuio; struct iovec *tvec; /* again, should have define */ +#endif register afs_int32 code; struct vrequest treq; @@ -118,8 +123,8 @@ afs_MemWrite(register struct vcache *avc, struct uio *auio, int aio, if ((code = afs_InitReq(&treq, acred))) return code; /* otherwise we read */ - totalLength = auio->afsio_resid; - filePos = auio->afsio_offset; + totalLength = AFS_UIO_RESID(auio); + filePos = AFS_UIO_OFFSET(auio); error = 0; transferLength = 0; afs_Trace4(afs_iclSetp, CM_TRACE_WRITE, ICL_TYPE_POINTER, avc, @@ -141,8 +146,8 @@ afs_MemWrite(register struct vcache *avc, struct uio *auio, int aio, */ osi_Assert(filePos <= avc->m.Length); diff = avc->m.Length - filePos; - auio->afsio_resid = MIN(totalLength, diff); - totalLength = auio->afsio_resid; + AFS_UIO_SETRESID(auio, MIN(totalLength, diff)); + totalLength = AFS_UIO_RESID(auio); } #else if (aio & IO_APPEND) { @@ -150,7 +155,8 @@ afs_MemWrite(register struct vcache *avc, struct uio *auio, int aio, #if defined(AFS_SUN56_ENV) auio->uio_loffset = 0; #endif - filePos = auio->afsio_offset = avc->m.Length; + filePos = avc->m.Length; + AFS_UIO_SETOFFSET(auio, filePos); } #endif /* @@ -184,7 +190,9 @@ afs_MemWrite(register struct vcache *avc, struct uio *auio, int aio, afs_FakeOpen(avc); #endif avc->states |= CDirty; +#ifndef AFS_DARWIN80_ENV tvec = (struct iovec *)osi_AllocSmallSpace(sizeof(struct iovec)); +#endif while (totalLength > 0) { /* * The following line is necessary because afs_GetDCache with @@ -254,13 +262,19 @@ afs_MemWrite(register struct vcache *avc, struct uio *auio, int aio, * as will fit */ len = max - offset; } + +#ifdef AFS_DARWIN80_ENV + trimlen = len; + tuiop = afsio_darwin_partialcopy(auio, trimlen); +#else /* mung uio structure to be right for this transfer */ afsio_copy(auio, &tuio, tvec); trimlen = len; afsio_trim(&tuio, trimlen); - tuio.afsio_offset = offset; +#endif + AFS_UIO_SETOFFSET(tuiop, offset); - code = afs_MemWriteUIO(tdc->f.inode, &tuio); + code = afs_MemWriteUIO(tdc->f.inode, tuiop); if (code) { void *mep; /* XXX in prototype world is struct memCacheEntry * */ error = code; @@ -275,7 +289,7 @@ afs_MemWrite(register struct vcache *avc, struct uio *auio, int aio, break; } /* otherwise we've written some, fixup length, etc and continue with next seg */ - len = len - tuio.afsio_resid; /* compute amount really transferred */ + len = len - AFS_UIO_RESID(tuiop); /* compute amount really transferred */ tlen = len; afsio_skip(auio, tlen); /* advance auio over data written */ /* compute new file size */ @@ -323,7 +337,11 @@ afs_MemWrite(register struct vcache *avc, struct uio *auio, int aio, avc->vc_error = error; if (!noLock) ReleaseWriteLock(&avc->lock); +#ifdef AFS_DARWIN80_ENV + uio_free(tuiop); +#else osi_FreeSmallSpace(tvec); +#endif error = afs_CheckCode(error, &treq, 6); return error; } @@ -347,8 +365,13 @@ afs_UFSWrite(register struct vcache *avc, struct uio *auio, int aio, volatile #endif afs_int32 error; +#ifdef AFS_DARWIN80_ENV + uio_t tuiop; +#else struct uio tuio; + struct uio *tuiop = &tuio; struct iovec *tvec; /* again, should have define */ +#endif struct osi_file *tfile; register afs_int32 code; struct vrequest treq; @@ -361,8 +384,8 @@ afs_UFSWrite(register struct vcache *avc, struct uio *auio, int aio, if ((code = afs_InitReq(&treq, acred))) return code; /* otherwise we read */ - totalLength = auio->afsio_resid; - filePos = auio->afsio_offset; + totalLength = AFS_UIO_RESID(auio); + filePos = AFS_UIO_OFFSET(auio); error = 0; transferLength = 0; afs_Trace4(afs_iclSetp, CM_TRACE_WRITE, ICL_TYPE_POINTER, avc, @@ -384,8 +407,8 @@ afs_UFSWrite(register struct vcache *avc, struct uio *auio, int aio, */ osi_Assert(filePos <= avc->m.Length); diff = avc->m.Length - filePos; - auio->afsio_resid = MIN(totalLength, diff); - totalLength = auio->afsio_resid; + AFS_UIO_SETRESID(auio, MIN(totalLength, diff)); + totalLength = AFS_UIO_RESID(auio); } #else if (aio & IO_APPEND) { @@ -393,7 +416,8 @@ afs_UFSWrite(register struct vcache *avc, struct uio *auio, int aio, #if defined(AFS_SUN56_ENV) auio->uio_loffset = 0; #endif - filePos = auio->afsio_offset = avc->m.Length; + filePos = avc->m.Length; + AFS_UIO_SETOFFSET(auio, avc->m.Length); } #endif /* @@ -427,7 +451,9 @@ afs_UFSWrite(register struct vcache *avc, struct uio *auio, int aio, afs_FakeOpen(avc); #endif avc->states |= CDirty; +#ifndef AFS_DARWIN80_ENV tvec = (struct iovec *)osi_AllocSmallSpace(sizeof(struct iovec)); +#endif while (totalLength > 0) { /* * The following line is necessary because afs_GetDCache with @@ -499,11 +525,18 @@ afs_UFSWrite(register struct vcache *avc, struct uio *auio, int aio, * as will fit */ len = max - offset; } + +#ifdef AFS_DARWIN80_ENV + trimlen = len; + tuiop = afsio_darwin_partialcopy(auio, trimlen); +#else /* mung uio structure to be right for this transfer */ afsio_copy(auio, &tuio, tvec); trimlen = len; afsio_trim(&tuio, trimlen); - tuio.afsio_offset = offset; +#endif + AFS_UIO_SETOFFSET(tuiop, offset); + #if defined(AFS_AIX41_ENV) AFS_GUNLOCK(); code = @@ -563,6 +596,10 @@ afs_UFSWrite(register struct vcache *avc, struct uio *auio, int aio, AFS_GUNLOCK(); code = osi_rdwr(tfile, &tuio, UIO_WRITE); AFS_GLOCK(); +#elif defined(AFS_DARWIN80_ENV) + AFS_GUNLOCK(); + code = VNOP_WRITE(tfile->vnode, tuiop, 0, afs_osi_ctxtp); + AFS_GLOCK(); #elif defined(AFS_DARWIN_ENV) AFS_GUNLOCK(); VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, current_proc()); @@ -600,7 +637,7 @@ afs_UFSWrite(register struct vcache *avc, struct uio *auio, int aio, break; } /* otherwise we've written some, fixup length, etc and continue with next seg */ - len = len - tuio.afsio_resid; /* compute amount really transferred */ + len = len - AFS_UIO_RESID(tuiop); /* compute amount really transferred */ tlen = len; afsio_skip(auio, tlen); /* advance auio over data written */ /* compute new file size */ @@ -651,7 +688,11 @@ afs_UFSWrite(register struct vcache *avc, struct uio *auio, int aio, avc->vc_error = error; if (!noLock) ReleaseWriteLock(&avc->lock); +#ifdef AFS_DARWIN80_ENV + uio_free(tuiop); +#else osi_FreeSmallSpace(tvec); +#endif #ifndef AFS_VM_RDWR_ENV /* * If write is implemented via VM, afs_fsync() is called from the high-level diff --git a/src/afs/afs.h b/src/afs/afs.h index 85e0186c8..7044b012d 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -527,12 +527,16 @@ struct SimpleLocks { #ifdef AFS_OSF_ENV #define CWired 0x00000800 /* OSF hack only */ #else +#ifdef AFS_DARWIN80_ENV +#define CDeadVnode 0x00000800 +#else #ifdef AFS_DARWIN_ENV #define CUBCinit 0x00000800 #else #define CWRITE_IGN 0x00000800 /* Next OS hack only */ #endif #endif +#endif #define CUnique 0x00001000 /* vc's uniquifier - latest unifiquier for fid */ #define CForeign 0x00002000 /* this is a non-afs vcache */ #define CUnlinked 0x00010000 @@ -546,6 +550,7 @@ struct SimpleLocks { #define CDCLock 0x02000000 /* Vnode lock held over call to GetDownD */ #define CBulkFetching 0x04000000 /* stats are being fetched by bulk stat */ #define CExtendedFile 0x08000000 /* extended file via ftruncate call. */ +#define CVInit 0x10000000 /* being initialized */ /* vcache vstate bits */ #define VRevokeWait 0x1 @@ -558,13 +563,20 @@ struct SimpleLocks { #define vrefCount v.v_count #endif /* AFS_XBSD_ENV */ -#if defined(AFS_LINUX24_ENV) +#if defined(AFS_DARWIN80_ENV) +#define VREFCOUNT_GT(v, y) vnode_isinuse(AFSTOV(v), (y)) +#elif defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) +#define VREFCOUNT(v) ((v)->vrefCount) +#define VREFCOUNT_GT(v, y) (AFSTOV(v)->v_usecount > (y)) +#elif defined(AFS_LINUX24_ENV) #define VREFCOUNT(v) atomic_read(&(AFSTOV(v)->v_count)) +#define VREFCOUNT_GT(v, y) ((atomic_read(&((vnode_t *) v)->v_count)>y)?1:0) #define VREFCOUNT_SET(v, c) atomic_set(&(AFSTOV(v)->v_count), c) #define VREFCOUNT_DEC(v) atomic_dec(&(AFSTOV(v)->v_count)) #define VREFCOUNT_INC(v) atomic_inc(&(AFSTOV(v)->v_count)) #else #define VREFCOUNT(v) ((v)->vrefCount) +#define VREFCOUNT_GT(v,y) ((v)->vrefCount > (y)) #define VREFCOUNT_SET(v, c) (v)->vrefCount = c; #define VREFCOUNT_DEC(v) (v)->vrefCount--; #define VREFCOUNT_INC(v) (v)->vrefCount++; @@ -581,7 +593,10 @@ struct SimpleLocks { extern afs_int32 vmPageHog; /* counter for # of vnodes which are page hogs. */ -#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_HAS_ALLOC_INODE)) +#if defined(AFS_DARWIN80_ENV) +#define VTOAFS(v) ((struct vcache *)vnode_fsnode((v))) +#define AFSTOV(vc) ((vc)->v) +#elif defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_HAS_ALLOC_INODE)) #define VTOAFS(v) ((struct vcache *)(v)->v_data) #define AFSTOV(vc) ((vc)->v) #else @@ -614,7 +629,11 @@ struct vcache { afs_uint32 Group; afs_uint16 Mode; /* XXXX Should be afs_int32 XXXX */ afs_uint16 LinkCount; +#ifdef AFS_DARWIN80_ENV + afs_uint16 Type; +#else /* vnode type is in v.v_type */ +#endif } m; afs_rwlock_t lock; /* The lock on the vcache contents. */ #if defined(AFS_SUN5_ENV) @@ -642,7 +661,9 @@ struct vcache { #ifdef AFS_AIX_ENV int ownslock; /* pid of owner of excl lock, else 0 - defect 3083 */ #endif -#ifdef AFS_DARWIN_ENV +#ifdef AFS_DARWIN80_ENV + lck_mtx_t *rwlock; +#elif defined(AFS_DARWIN_ENV) struct lock__bsd__ rwlock; #endif #ifdef AFS_XBSD_ENV diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index db2f9e1f5..7d5b15c4e 100644 --- a/src/afs/afs_call.c +++ b/src/afs/afs_call.c @@ -61,9 +61,13 @@ long afs_global_owner; simple_lock_data_t afs_global_lock; #endif -#if defined(AFS_DARWIN_ENV) +#if defined(AFS_DARWIN_ENV) +#ifdef AFS_DARWIN80_ENV +lck_mtx_t *afs_global_lock; +#else struct lock__bsd__ afs_global_lock; #endif +#endif #if defined(AFS_XBSD_ENV) && !defined(AFS_FBSD50_ENV) struct lock afs_global_lock; @@ -374,6 +378,9 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6) #endif } AFS_GLOCK(); +#ifdef AFS_DARWIN80_ENV + put_vfs_context(); +#endif #if defined(AFS_LINUX24_ENV) && defined(COMPLETION_H_EXISTS) && !defined(UKERNEL) if (parm < AFSOP_ADDCELL || parm == AFSOP_RXEVENT_DAEMON || parm == AFSOP_RXLISTENER_DAEMON) { @@ -654,11 +661,17 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6) while (afs_initState < AFSOP_START_BKG) afs_osi_Sleep(&afs_initState); +#ifdef AFS_DARWIN80_ENV + get_vfs_context(); +#endif /* do it by inode */ #ifdef AFS_SGI62_ENV ainode = (ainode << 32) | (parm3 & 0xffffffff); #endif code = afs_InitCacheFile(NULL, ainode); +#ifdef AFS_DARWIN80_ENV + put_vfs_context(); +#endif } else if (parm == AFSOP_ROOTVOLUME) { /* wait for basic init */ while (afs_initState < AFSOP_START_BKG) @@ -685,6 +698,9 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6) if (!code) { tbuffer[AFS_SMALLOCSIZ - 1] = '\0'; /* null-terminate the name */ /* We have the cache dir copied in. Call the cache init routine */ +#ifdef AFS_DARWIN80_ENV + get_vfs_context(); +#endif if (parm == AFSOP_CACHEFILE) code = afs_InitCacheFile(tbuffer, 0); else if (parm == AFSOP_CACHEINFO) @@ -693,6 +709,9 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6) code = afs_InitVolumeInfo(tbuffer); else if (parm == AFSOP_CELLINFO) code = afs_InitCellInfo(tbuffer); +#ifdef AFS_DARWIN80_ENV + put_vfs_context(); +#endif } osi_FreeSmallSpace(tbuffer); } else if (parm == AFSOP_GO) { @@ -840,10 +859,10 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6) i = rxi_Findcbi(parm2); mtu = ((i == -1) ? htonl(1500) : afs_cb_interface.mtu[i]); #else /* AFS_USERSPACE_IP_ADDR */ - struct ifnet *tifnp; + AFS_IFNET_T tifnp; tifnp = rxi_FindIfnet(parm2, NULL); /* make iterative */ - mtu = (tifnp ? tifnp->if_mtu : htonl(1500)); + mtu = (tifnp ? ifnet_mtu(tifnp) : htonl(1500)); #endif /* else AFS_USERSPACE_IP_ADDR */ #endif /* !AFS_SUN5_ENV */ if (!code) @@ -877,7 +896,7 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6) code = -1; } #else /* AFS_USERSPACE_IP_ADDR */ - struct ifnet *tifnp; + AFS_IFNET_T tifnp; tifnp = rxi_FindIfnet(parm2, &mask); /* make iterative */ if (!tifnp) @@ -930,6 +949,9 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6) code = EINVAL; out: +#ifdef AFS_DARWIN80_ENV /* to balance the put in afs3_syscall() */ + get_vfs_context(); +#endif AFS_GUNLOCK(); #ifdef AFS_LINUX20_ENV return -code; @@ -1248,7 +1270,7 @@ afs3_syscall(p, args, retval) struct proc *p; #endif void *args; - int *retval; + long *retval; { register struct a { long syscall; @@ -1370,7 +1392,10 @@ Afs_syscall() uap->parm6 = 0; } #endif - +#if defined(AFS_DARWIN80_ENV) + get_vfs_context(); + osi_Assert(*retval == 0); +#endif #if defined(AFS_HPUX_ENV) /* * There used to be code here (duplicated from osi_Init()) for @@ -1417,6 +1442,10 @@ Afs_syscall() code = afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4, p->td_ucred); +#elif defined(AFS_DARWIN80_ENV) + code = + afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4, + kauth_cred_get()); #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) code = afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3, uap->parm4, @@ -1505,6 +1534,9 @@ Afs_syscall() #endif } +#if defined(AFS_DARWIN80_ENV) + put_vfs_context(); +#endif #ifdef AFS_LINUX20_ENV code = -code; unlock_kernel(); diff --git a/src/afs/afs_callback.c b/src/afs/afs_callback.c index 1332e4880..2deab402a 100644 --- a/src/afs/afs_callback.c +++ b/src/afs/afs_callback.c @@ -151,7 +151,15 @@ SRXAFSCB_GetCE(struct rx_call *a_call, afs_int32 a_index, a_result->DataVersion = hgetlo(tvc->m.DataVersion); a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */ a_result->cbExpires = tvc->cbExpires; + if (tvc->states & CVInit) { + a_result->refCount = 1; + } else { +#ifdef AFS_DARWIN80_ENV + a_result->refCount = vnode_isinuse(AFSTOV(tvc),0)?1:0; /* XXX fix */ +#else a_result->refCount = VREFCOUNT(tvc); +#endif + } a_result->opens = tvc->opens; a_result->writers = tvc->execsOrWriters; a_result->mvstat = tvc->mvstat; @@ -230,7 +238,15 @@ SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index, a_result->DataVersion = hgetlo(tvc->m.DataVersion); a_result->callback = afs_data_pointer_to_int32(tvc->callback); /* XXXX Now a pointer; change it XXXX */ a_result->cbExpires = tvc->cbExpires; + if (tvc->states & CVInit) { + a_result->refCount = 1; + } else { +#ifdef AFS_DARWIN80_ENV + a_result->refCount = vnode_isinuse(AFSTOV(tvc),0)?1:0; /* XXX fix */ +#else a_result->refCount = VREFCOUNT(tvc); +#endif + } a_result->opens = tvc->opens; a_result->writers = tvc->execsOrWriters; a_result->mvstat = tvc->mvstat; @@ -407,7 +423,8 @@ ClearCallBack(register struct rx_connection *a_conn, else afs_evenCBs++; ReleaseWriteLock(&afs_xcbhash); - if (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR)) + if (!(tvc->states & CVInit) && + (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))) osi_dnlc_purgedp(tvc); afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK, ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32, @@ -451,7 +468,8 @@ ClearCallBack(register struct rx_connection *a_conn, afs_DequeueCallback(tvc); tvc->states &= ~(CStatd | CUnique | CBulkFetching); ReleaseWriteLock(&afs_xcbhash); - if (a_fid->Vnode & 1 || (vType(tvc) == VDIR)) + if (!(tvc->states & CVInit) && + (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))) osi_dnlc_purgedp(tvc); afs_Trace3(afs_iclSetp, CM_TRACE_CALLBACK, ICL_TYPE_POINTER, tvc, ICL_TYPE_INT32, diff --git a/src/afs/afs_cbqueue.c b/src/afs/afs_cbqueue.c index c995e31ba..3b98d3eaa 100644 --- a/src/afs/afs_cbqueue.c +++ b/src/afs/afs_cbqueue.c @@ -222,8 +222,9 @@ afs_CheckCallbacks(unsigned int secs) QRemove(tq); tq->prev = tq->next = NULL; tvc->states &= ~(CStatd | CMValid | CUnique); - if ((tvc->fid.Fid.Vnode & 1) - || (vType(tvc) == VDIR)) + if (!(tvc->states & CVInit) && + (tvc->fid.Fid.Vnode & 1 || + (vType(tvc) == VDIR))) osi_dnlc_purgedp(tvc); tvc->dchint = NULL; /*invalidate em */ afs_ResetVolumeInfo(tvp); @@ -239,7 +240,8 @@ afs_CheckCallbacks(unsigned int secs) QRemove(tq); tq->prev = tq->next = NULL; tvc->states &= ~(CStatd | CMValid | CUnique); - if ((tvc->fid.Fid.Vnode & 1) || (vType(tvc) == VDIR)) + if (!(tvc->states & CVInit) && + (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR))) osi_dnlc_purgedp(tvc); } } @@ -309,9 +311,10 @@ afs_FlushCBs(void) tvc->callback = 0; tvc->dchint = NULL; /* invalidate hints */ tvc->states &= ~(CStatd); - if ((tvc->fid.Fid.Vnode & 1) || (vType(tvc) == VDIR)) - osi_dnlc_purgedp(tvc); tvc->callsort.prev = tvc->callsort.next = NULL; + if (!(tvc->states & CVInit) && + ((tvc->fid.Fid.Vnode & 1) || (vType(tvc) == VDIR))) + osi_dnlc_purgedp(tvc); } afs_InitCBQueue(0); @@ -338,7 +341,8 @@ afs_FlushServerCBs(struct server *srvp) tvc->callback = 0; tvc->dchint = NULL; /* invalidate hints */ tvc->states &= ~(CStatd); - if ((tvc->fid.Fid.Vnode & 1) || (vType(tvc) == VDIR)) { + if (!(tvc->states & CVInit) && + ((tvc->fid.Fid.Vnode & 1) || (vType(tvc) == VDIR))) { osi_dnlc_purgedp(tvc); } afs_DequeueCallback(tvc); diff --git a/src/afs/afs_daemons.c b/src/afs/afs_daemons.c index fc1ad7329..60a77c31d 100644 --- a/src/afs/afs_daemons.c +++ b/src/afs/afs_daemons.c @@ -103,7 +103,12 @@ afs_CheckServerDaemon(void) } afs_CheckServerDaemonStarted = 0; } - +#define RECURSIVE_VFS_CONTEXT 1 +#if RECURSIVE_VFS_CONTEXT +extern int vfs_context_ref; +#else +#define vfs_context_ref 1 +#endif void afs_Daemon(void) { @@ -123,6 +128,18 @@ afs_Daemon(void) while (afs_initState < 101) afs_osi_Sleep(&afs_initState); +#ifdef AFS_DARWIN80_ENV + if (afs_osi_ctxtp_initialized) + osi_Panic("vfs context already initialized"); + while (afs_osi_ctxtp && vfs_context_ref) + afs_osi_Sleep(&afs_osi_ctxtp); +#if RECURSIVE_VFS_CONTEXT + if (afs_osi_ctxtp && !vfs_context_ref) + vfs_context_rele(afs_osi_ctxtp); +#endif + afs_osi_ctxtp = vfs_context_create(NULL); + afs_osi_ctxtp_initialized = 1; +#endif now = osi_Time(); lastCBSlotBump = now; @@ -302,6 +319,7 @@ afs_CheckRootVolume(void) afs_rootFid.Cell = localcell; if (afs_rootFid.Fid.Volume && afs_rootFid.Fid.Volume != volid && afs_globalVp) { + struct vcache *tvc = afs_globalVp; /* If we had a root fid before and it changed location we reset * the afs_globalVp so that it will be reevaluated. * Just decrement the reference count. This only occurs during @@ -354,8 +372,12 @@ afs_CheckRootVolume(void) out: crfree(credp); } +#else +#ifdef AFS_DARWIN80_ENV + afs_PutVCache(afs_globalVp); #else AFS_FAST_RELE(afs_globalVp); +#endif afs_globalVp = 0; #endif } diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index cd253e929..0e2357680 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -720,7 +720,7 @@ afs_GetDownD(int anumber, int *aneedSpace, afs_int32 buckethint) MReleaseWriteLock(&afs_xdcache); } - AFS_FAST_RELE(tvc); + afs_PutVCache(tvc); /*XXX was AFS_FAST_RELE?*/ MObtainWriteLock(&afs_xdcache, 528); if (afs_indexFlags[tdc->index] & (IFDataMod | IFDirtyPages | IFAnyPages)) diff --git a/src/afs/afs_init.c b/src/afs/afs_init.c index 219bd8b31..b2503aefd 100644 --- a/src/afs/afs_init.c +++ b/src/afs/afs_init.c @@ -352,6 +352,8 @@ afs_InitCacheInfo(register char *afile) struct statvfs st; #elif defined(AFS_DUX40_ENV) struct nstatfs st; +#elif defined(AFS_DARWIN80_ENV) + struct vfsstatfs st; #else struct statfs st; #endif /* SUN56 */ @@ -381,6 +383,9 @@ afs_InitCacheInfo(register char *afile) VFS_STATFS(filevp->v_vfsp, &st); TO_KERNEL_SPACE(); } +#elif defined(AFS_DARWIN80_ENV) + afs_cacheVfsp = vnode_mount(filevp); + if (afs_cacheVfsp && ((st = *(vfs_statfs(afs_cacheVfsp))),1)) #elif defined(AFS_DARWIN_ENV) if (!VFS_STATFS(filevp->v_mount, &st, current_proc())) #elif defined(AFS_FBSD50_ENV) @@ -413,7 +418,9 @@ afs_InitCacheInfo(register char *afile) #endif cacheInode = afs_vnodeToInumber(filevp); cacheDev.dev = afs_vnodeToDev(filevp); +#ifndef AFS_DARWIN80_ENV afs_cacheVfsp = filevp->v_vfsp; +#endif #endif /* AFS_LINUX20_ENV */ AFS_RELE(filevp); #endif /* AFS_LINUX22_ENV */ diff --git a/src/afs/afs_memcache.c b/src/afs/afs_memcache.c index 8e70a53de..d20d3cab8 100644 --- a/src/afs/afs_memcache.c +++ b/src/afs/afs_memcache.c @@ -180,13 +180,13 @@ afs_MemReadUIO(ino_t blkno, struct uio *uioP) { register struct memCacheEntry *mceP = (struct memCacheEntry *)afs_MemCacheOpen(blkno); - int length = mceP->size - uioP->uio_offset; + int length = mceP->size - AFS_UIO_OFFSET(uioP); afs_int32 code; AFS_STATCNT(afs_MemReadUIO); MObtainReadLock(&mceP->afs_memLock); - length = (length < uioP->uio_resid) ? length : uioP->uio_resid; - AFS_UIOMOVE(mceP->data + uioP->uio_offset, length, UIO_READ, uioP, code); + length = (length < AFS_UIO_RESID(uioP)) ? length : AFS_UIO_RESID(uioP); + AFS_UIOMOVE(mceP->data + AFS_UIO_OFFSET(uioP), length, UIO_READ, uioP, code); MReleaseReadLock(&mceP->afs_memLock); return code; } @@ -281,25 +281,25 @@ afs_MemWriteUIO(ino_t blkno, struct uio *uioP) AFS_STATCNT(afs_MemWriteUIO); MObtainWriteLock(&mceP->afs_memLock, 312); - if (uioP->uio_resid + uioP->uio_offset > mceP->dataSize) { + if (AFS_UIO_RESID(uioP) + AFS_UIO_OFFSET(uioP) > mceP->dataSize) { char *oldData = mceP->data; - mceP->data = afs_osi_Alloc(uioP->uio_resid + uioP->uio_offset); + mceP->data = afs_osi_Alloc(AFS_UIO_RESID(uioP) + AFS_UIO_OFFSET(uioP)); AFS_GUNLOCK(); memcpy(mceP->data, oldData, mceP->size); AFS_GLOCK(); afs_osi_Free(oldData, mceP->dataSize); - mceP->dataSize = uioP->uio_resid + uioP->uio_offset; + mceP->dataSize = AFS_UIO_RESID(uioP) + AFS_UIO_OFFSET(uioP); } - if (mceP->size < uioP->uio_offset) + if (mceP->size < AFS_UIO_OFFSET(uioP)) memset(mceP->data + mceP->size, 0, - (int)(uioP->uio_offset - mceP->size)); - AFS_UIOMOVE(mceP->data + uioP->uio_offset, uioP->uio_resid, UIO_WRITE, + (int)(AFS_UIO_OFFSET(uioP) - mceP->size)); + AFS_UIOMOVE(mceP->data + AFS_UIO_OFFSET(uioP), AFS_UIO_RESID(uioP), UIO_WRITE, uioP, code); - if (uioP->uio_offset > mceP->size) - mceP->size = uioP->uio_offset; + if (AFS_UIO_OFFSET(uioP) > mceP->size) + mceP->size = AFS_UIO_OFFSET(uioP); MReleaseWriteLock(&mceP->afs_memLock); return code; diff --git a/src/afs/afs_osi.c b/src/afs/afs_osi.c index 3ea337ace..eeebdf29b 100644 --- a/src/afs/afs_osi.c +++ b/src/afs/afs_osi.c @@ -60,7 +60,9 @@ osi_Init(void) #elif defined(AFS_FBSD50_ENV) mtx_init(&afs_global_mtx, "AFS global lock", NULL, MTX_DEF); #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) +#if !defined(AFS_DARWIN80_ENV) lockinit(&afs_global_lock, PLOCK, "afs global lock", 0, 0); +#endif afs_global_owner = 0; #elif defined(AFS_AIX41_ENV) lock_alloc((void *)&afs_global_lock, LOCK_ALLOC_PIN, 1, 1); @@ -74,6 +76,11 @@ osi_Init(void) #endif /* AFS_HPUX_ENV */ if (!afs_osicred_initialized) { +#if defined(AFS_DARWIN80_ENV) + afs_osi_ctxtp_initialized = 0; + afs_osi_ctxtp = NULL; /* initialized in afs_Daemon since it has + a proc reference that cannot be changed */ +#endif #if defined(AFS_XBSD_ENV) /* Can't just invent one, must use crget() because of mutex */ afs_osi_credp = crdup(osi_curcred()); @@ -82,7 +89,12 @@ osi_Init(void) #if defined(AFS_LINUX26_ENV) afs_osi_cred.cr_group_info = groups_alloc(0); #endif +#if defined(AFS_DARWIN80_ENV) + afs_osi_cred.cr_ref = 1; /* kauth_cred_get_ref needs 1 existing ref */ +#else crhold(&afs_osi_cred); /* don't let it evaporate */ +#endif + afs_osi_credp = &afs_osi_cred; #endif afs_osicred_initialized = 1; @@ -284,6 +296,7 @@ afs_osi_Invisible(void) curproc->p_flag |= SSYS; #elif defined(AFS_HPUX101_ENV) && !defined(AFS_HPUX1123_ENV) set_system_proc(u.u_procp); +#elif defined(AFS_DARWIN80_ENV) #elif defined(AFS_DARWIN_ENV) /* maybe call init_process instead? */ current_proc()->p_flag |= P_SYSTEM; @@ -333,9 +346,11 @@ afs_osi_SetTime(osi_timeval_t * atv) stime(&sta); AFS_GLOCK(); #elif defined(AFS_DARWIN_ENV) +#ifndef AFS_DARWIN80_ENV AFS_GUNLOCK(); setthetime(atv); AFS_GLOCK(); +#endif #else /* stolen from kern_time.c */ #ifndef AFS_AUX_ENV @@ -560,6 +575,13 @@ void shutdown_osi(void) { AFS_STATCNT(shutdown_osi); +#ifdef AFS_DARWIN80_ENV + if (afs_osi_ctxtp_initialized && afs_osi_ctxtp) { + vfs_context_rele(afs_osi_ctxtp); + afs_osi_ctxtp = NULL; + afs_osi_ctxtp_initialized = 0; + } +#endif if (afs_cold_shutdown) { LOCK_INIT(&afs_ftf, "afs_ftf"); } @@ -765,7 +787,7 @@ afs_osi_TraverseProcTable(void) } #endif -#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if (defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN80_ENV)) || defined(AFS_FBSD_ENV) void afs_osi_TraverseProcTable(void) { @@ -989,6 +1011,25 @@ afs_osi_proc2cred(AFS_PROC * pr) return rv; } +#elif defined(AFS_DARWIN80_ENV) +const struct AFS_UCRED * +afs_osi_proc2cred(AFS_PROC * pr) +{ + struct AFS_UCRED *rv = NULL; + static struct AFS_UCRED cr; + struct ucred *pcred; + + if (pr == NULL) { + return NULL; + } + pcred = proc_ucred(pr); + cr.cr_ref = 1; + cr.cr_uid = pcred->cr_uid; + cr.cr_ngroups = pcred->cr_ngroups; + memcpy(cr.cr_groups, pcred->cr_groups, + NGROUPS * sizeof(gid_t)); + return &cr; +} #elif defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) const struct AFS_UCRED * afs_osi_proc2cred(AFS_PROC * pr) diff --git a/src/afs/afs_osi.h b/src/afs/afs_osi.h index 99ce3137f..af2c03d01 100644 --- a/src/afs/afs_osi.h +++ b/src/afs/afs_osi.h @@ -123,6 +123,14 @@ struct afs_osi_WaitHandle { /* * Vnode related macros */ +#if defined(AFS_DARWIN80_ENV) +#define vType(vc) vnode_vtype(AFSTOV(vc)) +#define vSetVfsp(vc, vfsp) +#define vSetType(vc, type) (vc)->m.Type = (type) +extern int afs_vfs_typenum; +#define SetAfsVnode(vn) /* nothing; done in getnewvnode() */ +#define IsAfsVnode(v) (vfs_typenum(vnode_mount((v))) == afs_vfs_typenum) +#else #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_LINUX22_ENV) #define vSetVfsp(vc, vfsp) AFSTOV(vc)->v_mount = (vfsp) #define vSetType(vc, type) AFSTOV(vc)->v_type = (type) @@ -132,7 +140,6 @@ struct afs_osi_WaitHandle { #define vSetType(vc,type) (vc)->v.v_type = (type) #define vSetVfsp(vc,vfsp) (vc)->v.v_vfsp = (vfsp) #endif - #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) extern int (**afs_vnodeop_p) (); #define IsAfsVnode(v) ((v)->v_op == afs_vnodeop_p) @@ -142,6 +149,7 @@ extern struct vnodeops *afs_ops; #define IsAfsVnode(v) ((v)->v_op == afs_ops) #define SetAfsVnode(v) (v)->v_op = afs_ops #endif +#endif #ifdef AFS_SGI65_ENV #define gop_lookupname(fnamep,segflg,followlink,compvpp) \ @@ -192,6 +200,8 @@ typedef struct timeval osi_timeval_t; #define osi_getpid() getpid() +#define osi_getpid() getpid() + /* * osi_ThreadUnique() should yield a value that can be found in ps * output in order to draw correspondences between ICL traces and what @@ -272,6 +282,11 @@ typedef struct timeval osi_timeval_t; * and kernel space. Call these to avoid taking page faults while * holding the global lock. */ +#ifdef CAST_USER_ADDR_T +#define __U(X) CAST_USER_ADDR_T((X)) +#else +#define __U(X) (X) +#endif #ifdef AFS_GLOBAL_SUNLOCK #define AFS_COPYIN(SRC,DST,LEN,CODE) \ @@ -279,7 +294,7 @@ typedef struct timeval osi_timeval_t; int haveGlock = ISAFS_GLOCK(); \ if (haveGlock) \ AFS_GUNLOCK(); \ - CODE = copyin((SRC),(DST),(LEN)); \ + CODE = copyin(__U((SRC)),(DST),(LEN)); \ if (haveGlock) \ AFS_GLOCK(); \ } while(0) @@ -289,7 +304,7 @@ typedef struct timeval osi_timeval_t; int haveGlock = ISAFS_GLOCK(); \ if (haveGlock) \ AFS_GUNLOCK(); \ - CODE = copyinstr((SRC),(DST),(LEN),(CNT)); \ + CODE = copyinstr(__U((SRC)),(DST),(LEN),(CNT)); \ if (haveGlock) \ AFS_GLOCK(); \ } while(0) @@ -299,11 +314,23 @@ typedef struct timeval osi_timeval_t; int haveGlock = ISAFS_GLOCK(); \ if (haveGlock) \ AFS_GUNLOCK(); \ - CODE = copyout((SRC),(DST),(LEN)); \ + CODE = copyout((SRC),__U((DST)),(LEN)); \ if (haveGlock) \ AFS_GLOCK(); \ } while(0) +#if defined(AFS_DARWIN80_ENV) +#define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ + do { \ + int haveGlock = ISAFS_GLOCK(); \ + if (haveGlock) \ + AFS_GUNLOCK(); \ + uio_setrw((UIO),(RW)); \ + CODE = uiomove((SRC),(LEN),(UIO)); \ + if (haveGlock) \ + AFS_GLOCK(); \ + } while(0) +#else #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ do { \ @@ -326,24 +353,32 @@ typedef struct timeval osi_timeval_t; AFS_GLOCK(); \ } while(0) #endif +#endif /* AFS_DARWIN80_ENV */ #else /* AFS_GLOBAL_SUNLOCK */ #define AFS_COPYIN(SRC,DST,LEN,CODE) \ do { \ - CODE = copyin((SRC),(DST),(LEN)); \ + CODE = copyin(__U((SRC)),(DST),(LEN)); \ } while(0) #define AFS_COPYINSTR(SRC,DST,LEN,CNT,CODE) \ do { \ - CODE = copyinstr((SRC),(DST),(LEN),(CNT)); \ + CODE = copyinstr(__U((SRC)),(DST),(LEN),(CNT)); \ } while(0) #define AFS_COPYOUT(SRC,DST,LEN,CODE) \ do { \ - CODE = copyout((SRC),(DST),(LEN)); \ + CODE = copyout((SRC),__U((DST)),(LEN)); \ } while(0) +#if defined(AFS_DARWIN80_ENV) +#define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ + do { \ + uio_setrw((UIO),(RW)); \ + CODE = uiomove((SRC),(LEN),(UIO)); \ + } while(0) +#else /* AFS_OSF_ENV || AFS_FBSD_ENV */ #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) #define AFS_UIOMOVE(SRC,LEN,RW,UIO,CODE) \ do { \ @@ -356,9 +391,23 @@ typedef struct timeval osi_timeval_t; CODE = uiomove((SRC),(LEN),(RW),(UIO)); \ } while(0) #endif /* AFS_OSF_ENV || AFS_FBSD_ENV */ +#endif /* AFS_DARWIN80_ENV */ #endif /* AFS_GLOBAL_SUNLOCK */ +#ifdef AFS_DARWIN80_ENV +#define AFS_UIO_OFFSET(uio) (int)uio_offset(uio) +#define AFS_UIO_RESID(uio) (int)uio_resid(uio) +#define AFS_UIO_SETOFFSET(uio, off) uio_setoffset(uio, off) +#define AFS_UIO_SETRESID(uio, val) uio_setresid(uio, val) +#else +#define AFS_UIO_OFFSET(uio) (uio)->uio_offset +#define AFS_UIO_RESID(uio) (uio)->uio_resid +#define AFS_UIO_SETOFFSET(uio, off) (uio)->uio_offset = off +#define AFS_UIO_SETRESID(uio, val) (uio)->uio_resid = val +#endif + + /* * encapsulation of kernel data structure accesses */ diff --git a/src/afs/afs_osi_pag.c b/src/afs/afs_osi_pag.c index eb5199688..8d49baf53 100644 --- a/src/afs/afs_osi_pag.c +++ b/src/afs/afs_osi_pag.c @@ -241,6 +241,12 @@ afs_setpag(void) code = AddPag(genpag(), &credp); crfree(credp); } +#elif defined(AFS_DARWIN80_ENV) + { + struct ucred *credp = kauth_cred_proc_ref(p); + code = AddPag(p, genpag(), &credp); + kauth_cred_rele(credp); + } #elif defined(AFS_DARWIN_ENV) { struct ucred *credp = crdup(p->p_cred->pc_ucred); diff --git a/src/afs/afs_osi_uio.c b/src/afs/afs_osi_uio.c index 953647db3..8b61efea1 100644 --- a/src/afs/afs_osi_uio.c +++ b/src/afs/afs_osi_uio.c @@ -25,6 +25,7 @@ RCSID * UIO routines */ +#ifndef AFS_DARWIN80_ENV /* routine to make copy of uio structure in ainuio, using aoutvec for space */ int afsio_copy(struct uio *ainuio, struct uio *aoutuio, @@ -76,6 +77,7 @@ afsio_trim(register struct uio *auio, register afs_int32 asize) } return 0; } +#endif /* skip asize bytes in the current uio structure */ int @@ -85,6 +87,9 @@ afsio_skip(register struct uio *auio, register afs_int32 asize) register int cnt; AFS_STATCNT(afsio_skip); +#ifdef AFS_DARWIN80_ENV + uio_update(auio, asize); +#else /* It isn't guaranteed that multiple iovecs work ok (hasn't been tested!) */ while (asize > 0 && auio->afsio_resid) { tv = auio->afsio_iov; @@ -102,5 +107,6 @@ afsio_skip(register struct uio *auio, register afs_int32 asize) auio->afsio_offset += cnt; asize -= cnt; } +#endif return 0; } diff --git a/src/afs/afs_osi_vget.c b/src/afs/afs_osi_vget.c index 40e0a9bb6..aea7f7ac8 100644 --- a/src/afs/afs_osi_vget.c +++ b/src/afs/afs_osi_vget.c @@ -23,7 +23,7 @@ RCSID -#if !defined(AFS_LINUX20_ENV) +#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN80_ENV) /* This is the common part of the vget VFS call. */ int afs_osi_vget(struct vcache **avcpp, struct fid *afidp, struct vrequest *areqp) diff --git a/src/afs/afs_osidnlc.c b/src/afs/afs_osidnlc.c index 919d2f2f0..ab856edad 100644 --- a/src/afs/afs_osidnlc.c +++ b/src/afs/afs_osidnlc.c @@ -242,6 +242,9 @@ osi_dnlc_lookup(struct vcache *adp, char *aname, int locktype) #ifdef AFS_OSF_ENV VN_HOLD((vnode_t *) tvc); #else +#ifdef AFS_DARWIN80_ENV + vnode_get(tvc->v); +#endif osi_vnhold(tvc, 0); #endif ReleaseReadLock(&afs_xvcache); diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index 27cab48d0..32d6dab6c 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -430,7 +430,7 @@ afs_ioctl(OSI_VN_DECL(tvc), int cmd, void *arg, int flag, cred_t * cr, interface call. */ /* AFS_HPUX102 and up uses VNODE ioctl instead */ -#ifndef AFS_HPUX102_ENV +#if !defined(AFS_HPUX102_ENV) && !defined(AFS_DARWIN80_ENV) #if !defined(AFS_SGI_ENV) #ifdef AFS_AIX32_ENV #ifdef AFS_AIX51_ENV @@ -817,9 +817,15 @@ afs_pioctl(p, args, retval) } *uap = (struct a *)args; AFS_STATCNT(afs_pioctl); +#ifdef AFS_DARWIN80_ENV + return (afs_syscall_pioctl + (uap->path, uap->cmd, uap->cmarg, uap->follow, + kauth_cred_get())); +#else return (afs_syscall_pioctl (uap->path, uap->cmd, uap->cmarg, uap->follow, p->p_cred->pc_ucred)); +#endif } #endif @@ -1453,8 +1459,10 @@ DECL_PIOCTL(PSetTokens) #else struct proc *p = curproc; /* XXX */ #endif +#ifndef AFS_DARWIN80_ENV uprintf("Process %d (%s) tried to change pags in PSetTokens\n", p->p_pid, p->p_comm); +#endif if (!setpag(p, acred, -1, &pag, 1)) { #else #ifdef AFS_OSF_ENV @@ -2542,12 +2550,25 @@ DECL_PIOCTL(PFlushVolumeData) * Clear stat'd flag from all vnodes from this volume; this will invalidate all * the vcaches associated with the volume. */ + loop: ObtainReadLock(&afs_xvcache); i = VCHashV(&avc->fid); for (tq = afs_vhashTV[i].prev; tq != &afs_vhashTV[i]; tq = uq) { uq = QPrev(tq); tvc = QTOVH(tq); if (tvc->fid.Fid.Volume == volume && tvc->fid.Cell == cell) { + if (tvc->states & CVInit) { + ReleaseReadLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + goto loop; + } +#ifdef AFS_DARWIN80_ENV + if (tvc->states & CDeadVnode) { + ReleaseReadLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + goto loop; + } +#endif #if defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV) VN_HOLD(AFSTOV(tvc)); #else @@ -2574,9 +2595,15 @@ DECL_PIOCTL(PFlushVolumeData) #ifdef AFS_BOZONLOCK_ENV afs_BozonUnlock(&tvc->pvnLock, tvc); #endif +#ifdef AFS_DARWIN80_ENV + /* our tvc ptr is still good until now */ + AFS_FAST_RELE(tvc); + ObtainReadLock(&afs_xvcache); +#else ObtainReadLock(&afs_xvcache); /* our tvc ptr is still good until now */ AFS_FAST_RELE(tvc); +#endif } } ReleaseReadLock(&afs_xvcache); diff --git a/src/afs/afs_server.c b/src/afs/afs_server.c index ec1c31ae2..6ba3e3efb 100644 --- a/src/afs/afs_server.c +++ b/src/afs/afs_server.c @@ -1139,24 +1139,43 @@ afsi_SetServerIPRank(struct srvAddr *sa, struct in_ifaddr *ifa) void afsi_SetServerIPRank(sa, ifa) struct srvAddr *sa; +#ifdef AFS_DARWIN80_ENV + ifaddr_t ifa; +#else struct ifaddr *ifa; +#endif { + struct sockaddr sout; struct sockaddr_in *sin; int t; afs_uint32 subnetmask, myAddr, myNet, myDstaddr, mySubnet, netMask; afs_uint32 serverAddr; - if (ifa->ifa_addr->sa_family != AF_INET) + if (ifaddr_address_family(ifa) != AF_INET) return; - sin = (struct sockaddr_in *)ifa->ifa_addr; - myAddr = ntohl(sin->sin_addr.s_addr); /* one of my IP addr in host order */ + t = ifaddr_address(ifa, &sout, sizeof(sout)); + if (t == 0) { + sin = (struct sockaddr_in *)&sout; + myAddr = ntohl(sin->sin_addr.s_addr); /* one of my IP addr in host order */ + } else { + myAddr = 0; + } serverAddr = ntohl(sa->sa_ip); /* server's IP addr in host order */ - sin = (struct sockaddr_in *)ifa->ifa_netmask; - subnetmask = ntohl(sin->sin_addr.s_addr); /* subnet mask in host order */ - sin = (struct sockaddr_in *)ifa->ifa_dstaddr; - if (sin) + t = ifaddr_netmask(ifa, &sout, sizeof(sout)); + if (t == 0) { + sin = (struct sockaddr_in *)&sout; + subnetmask = ntohl(sin->sin_addr.s_addr); /* subnet mask in host order */ + } else { + subnetmask = 0; + } + t = ifaddr_dstaddress(ifa, &sout, sizeof(sout)); + if (t == 0) { + sin = (struct sockaddr_in *)&sout; myDstaddr = sin->sin_addr.s_addr; + } else { + myDstaddr = 0; + } if (IN_CLASSA(myAddr)) netMask = IN_CLASSA_NET; @@ -1175,20 +1194,20 @@ afsi_SetServerIPRank(sa, ifa) if (serverAddr == myAddr) { /* same machine */ sa->sa_iprank = afs_min(sa->sa_iprank, TOPR); } else { /* same subnet */ - sa->sa_iprank = afs_min(sa->sa_iprank, HI + ifa->ifa_metric); + sa->sa_iprank = afs_min(sa->sa_iprank, HI + ifnet_metric(ifaddr_ifnet(ifa))); } } else { /* same net */ - sa->sa_iprank = afs_min(sa->sa_iprank, MED + ifa->ifa_metric); + sa->sa_iprank = afs_min(sa->sa_iprank, MED + ifnet_metric(ifaddr_ifnet(ifa))); } } #ifdef IFF_POINTTOPOINT /* check for case #4 -- point-to-point link */ - if ((ifa->ia_ifp->if_flags & IFF_POINTOPOINT) + if ((ifnet_flags(ifaddr_ifnet(ifa)) & IFF_POINTOPOINT) && (myDstaddr == serverAddr)) { - if (ifa->ia_ifp->if_metric >= (MAXDEFRANK - MED) / PPWEIGHT) + if (ifnet_metric(ifaddr_ifnet(ifa)) >= (MAXDEFRANK - MED) / PPWEIGHT) t = MAXDEFRANK; else - t = MED + (PPWEIGHT << ifa->->ifa_metric); + t = MED + (PPWEIGHT << ifnet_metric(ifaddr_ifnet(ifa))); if (sa->sa_iprank > t) sa->sa_iprank = t; } @@ -1361,6 +1380,20 @@ static int afs_SetServerPrefs(struct srvAddr *sa) { #ifdef AFS_SGI62_ENV (void)hash_enum(&hashinfo_inaddr, afsi_enum_set_rank, HTF_INET, NULL, (caddr_t) sa, NULL); +#elif defined(AFS_DARWIN80_ENV) + { + errno_t t; + int cnt=0; + ifaddr_t *addresses, address; + t = ifnet_get_address_list_family(NULL, &addresses, AF_INET); + if (t == 0) { + while(addresses[cnt] != NULL) { + afsi_SetServerIPRank(sa, address); + cnt++; + } + ifnet_free_address_list(addresses); + } + } #elif defined(AFS_DARWIN60_ENV) { struct ifnet *ifn; diff --git a/src/afs/afs_util.c b/src/afs/afs_util.c index 0d6e37c99..de42fbd1b 100644 --- a/src/afs/afs_util.c +++ b/src/afs/afs_util.c @@ -270,10 +270,15 @@ afs_CheckLocks(void) for (i = 0; i < VCSIZE; i++) { for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) { + if (tvc->states & CVInit) continue; #ifdef AFS_OSF_ENV if (VREFCOUNT(tvc) > 1) #else /* AFS_OSF_ENV */ +#ifdef AFS_DARWIN80_ENV + if (vnode_isinuse(AFSTOV(tvc), 0)) +#else if (VREFCOUNT(tvc)) +#endif #endif afs_warn("Stat cache entry at %x is held\n", tvc); if (CheckLock(&tvc->lock)) diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index cf626316f..a728ab4c0 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -194,8 +194,13 @@ afs_FlushVCache(struct vcache *avc, int *slept) /* OK, there are no internal vrefCounts, so there shouldn't * be any more refs here. */ if (avc->v) { +#ifdef AFS_DARWIN80_ENV + vnode_clearfsnode(AFSTOV(avc)); + vnode_removefsref(AFSTOV(avc)); +#else avc->v->v_data = NULL; /* remove from vnode */ - avc->v = NULL; /* also drop the ptr to vnode */ +#endif + AFSTOV(avc) = NULL; /* also drop the ptr to vnode */ } #endif afs_FreeAllAxs(&(avc->Access)); @@ -238,7 +243,7 @@ afs_FlushVCache(struct vcache *avc, int *slept) /* This should put it back on the vnode free list since usecount is 1 */ afs_vcount--; vSetType(avc, VREG); - if (VREFCOUNT(avc) > 0) { + if (VREFCOUNT_GT(avc,0)) { #if defined(AFS_OSF_ENV) VN_UNLOCK(AFSTOV(avc)); #endif @@ -625,7 +630,7 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) refpanic("Exceeded pool of AFS vnodes(VLRU cycle?)"); } else if (QNext(uq) != tq) { refpanic("VLRU inconsistent"); - } else if (VREFCOUNT(tvc) < 1) { + } else if (!VREFCOUNT_GT(tvc,0)) { refpanic("refcnt 0 on VLRU"); } @@ -673,7 +678,8 @@ restart: } #endif - if (VREFCOUNT(tvc) == 1 && tvc->opens == 0 + if (VREFCOUNT_GT(tvc,0) && !VREFCOUNT_GT(tvc,1) && + tvc->opens == 0 && (tvc->states & CUnlinkedDel) == 0) { code = afs_FlushVCache(tvc, &fv_slept); if (code == 0) { @@ -744,15 +750,32 @@ restart: #endif } else if (QNext(uq) != tq) { refpanic("VLRU inconsistent"); + } else if (tvc->states & CVInit) { + continue; } - - if (((VREFCOUNT(tvc) == 0) -#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL) - || ((VREFCOUNT(tvc) == 1) && - (UBCINFOEXISTS(AFSTOV(tvc)))) + + if (!VREFCOUNT_GT(tvc,0) +#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL) && !defined(AFS_DARWIN80_ENV) + || ((VREFCOUNT(tvc) == 1) && + (UBCINFOEXISTS(AFSTOV(tvc)))) #endif - ) && tvc->opens == 0 && (tvc->states & CUnlinkedDel) == 0) { + && tvc->opens == 0 && (tvc->states & CUnlinkedDel) == 0) { #if defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) +#ifdef AFS_DARWIN80_ENV + fv_slept=1; + /* must release lock, since vnode_recycle will immediately + reclaim if there are no other users */ + ReleaseWriteLock(&afs_xvcache); + AFS_GUNLOCK(); + /* VREFCOUNT_GT only sees usecounts, not iocounts */ + /* so this may fail to actually recycle the vnode now */ + if (vnode_recycle(AFSTOV(tvc))) + code=0; + else + code=EBUSY; + AFS_GLOCK(); + ObtainWriteLock(&afs_xvcache, 336); +#else /* * vgone() reclaims the vnode, which calls afs_FlushVCache(), * then it puts the vnode on the free list. @@ -762,8 +785,10 @@ restart: */ AFS_GUNLOCK(); vgone(AFSTOV(tvc)); + fv_slept = 0; + code = 0; AFS_GLOCK(); - code = fv_slept = 0; +#endif #else code = afs_FlushVCache(tvc, &fv_slept); #endif @@ -832,22 +857,76 @@ restart: RWLOCK_INIT(&tvc->vlock, "vcache vlock"); #endif /* defined(AFS_SUN5_ENV) */ + tvc->parentVnode = 0; + tvc->mvid = NULL; + tvc->linkData = NULL; + tvc->cbExpires = 0; + tvc->opens = 0; + tvc->execsOrWriters = 0; + tvc->flockCount = 0; + tvc->anyAccess = 0; + tvc->states = CVInit; + tvc->last_looker = 0; + tvc->fid = *afid; + tvc->asynchrony = -1; + tvc->vc_error = 0; +#ifdef AFS_TEXT_ENV + tvc->flushDV.low = tvc->flushDV.high = AFS_MAXDV; +#endif + hzero(tvc->mapDV); + tvc->truncPos = AFS_NOTRUNC; /* don't truncate until we need to */ + hzero(tvc->m.DataVersion); /* in case we copy it into flushDV */ + tvc->Access = NULL; + tvc->callback = serverp; /* to minimize chance that clear + * request is lost */ + + i = VCHash(afid); + j = VCHashV(afid); + + tvc->hnext = afs_vhashT[i]; + tvc->vhnext = afs_vhashTV[j]; + afs_vhashT[i] = afs_vhashTV[j] = tvc; + + if ((VLRU.next->prev != &VLRU) || (VLRU.prev->next != &VLRU)) { + refpanic("NewVCache VLRU inconsistent"); + } + QAdd(&VLRU, &tvc->vlruq); /* put in lruq */ + if ((VLRU.next->prev != &VLRU) || (VLRU.prev->next != &VLRU)) { + refpanic("NewVCache VLRU inconsistent2"); + } + if (tvc->vlruq.next->prev != &(tvc->vlruq)) { + refpanic("NewVCache VLRU inconsistent3"); + } + if (tvc->vlruq.prev->next != &(tvc->vlruq)) { + refpanic("NewVCache VLRU inconsistent4"); + } + vcachegen++; +/* it should now be safe to drop the xvcache lock */ #ifdef AFS_OBSD_ENV + ReleaseWriteLock(&afs_xvcache); AFS_GUNLOCK(); afs_nbsd_getnewvnode(tvc); /* includes one refcount */ AFS_GLOCK(); + ObtainWriteLock(&afs_xvcache,337); lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0); #endif #ifdef AFS_DARWIN_ENV + ReleaseWriteLock(&afs_xvcache); AFS_GUNLOCK(); afs_darwin_getnewvnode(tvc); /* includes one refcount */ AFS_GLOCK(); + ObtainWriteLock(&afs_xvcache,338); +#ifdef AFS_DARWIN80_ENV + LOCKINIT(tvc->rwlock); +#else lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0); #endif +#endif #ifdef AFS_FBSD_ENV { struct vnode *vp; + ReleaseWriteLock(&afs_xvcache); AFS_GUNLOCK(); #if defined(AFS_FBSD60_ENV) if (getnewvnode(MOUNT_AFS, afs_globalVFS, &afs_vnodeops, &vp)) @@ -858,6 +937,7 @@ restart: #endif panic("afs getnewvnode"); /* can't happen */ AFS_GLOCK(); + ObtainWriteLock(&afs_xvcache,339); if (tvc->v != NULL) { /* I'd like to know if this ever happens... * We don't drop global for the rest of this function, @@ -876,25 +956,6 @@ restart: lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0); } #endif - tvc->parentVnode = 0; - tvc->mvid = NULL; - tvc->linkData = NULL; - tvc->cbExpires = 0; - tvc->opens = 0; - tvc->execsOrWriters = 0; - tvc->flockCount = 0; - tvc->anyAccess = 0; - tvc->states = 0; - tvc->last_looker = 0; - tvc->fid = *afid; - tvc->asynchrony = -1; - tvc->vc_error = 0; -#ifdef AFS_TEXT_ENV - tvc->flushDV.low = tvc->flushDV.high = AFS_MAXDV; -#endif - hzero(tvc->mapDV); - tvc->truncPos = AFS_NOTRUNC; /* don't truncate until we need to */ - hzero(tvc->m.DataVersion); /* in case we copy it into flushDV */ #if defined(AFS_OSF_ENV) || defined(AFS_LINUX22_ENV) /* Hold it for the LRU (should make count 2) */ @@ -931,9 +992,6 @@ restart: afs_BozonInit(&tvc->pvnLock, tvc); #endif - tvc->Access = NULL; - tvc->callback = serverp; /* to minimize chance that clear - * request is lost */ /* initialize vnode data, note vrefCount is v.v_count */ #ifdef AFS_AIX_ENV /* Don't forget to free the gnode space */ @@ -1027,6 +1085,9 @@ restart: i = VCHash(afid); j = VCHashV(afid); + tvc->states &=~ CVInit; + afs_osi_Wakeup(&tvc->states); + tvc->hnext = afs_vhashT[i]; afs_vhashT[i] = tvc; QAdd(&afs_vhashTV[i], &tvc->vhashq); @@ -1077,6 +1138,12 @@ afs_FlushActiveVcaches(register afs_int32 doflocks) ObtainReadLock(&afs_xvcache); for (i = 0; i < VCSIZE; i++) { for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) { + if (tvc->states & CVInit) continue; +#ifdef AFS_DARWIN80_ENV + if (tvc->states & CDeadVnode && + (tvc->states & (CCore|CUnlinkedDel) || + tvc->flockCount)) panic("Dead vnode has core/unlinkedel/flock"); +#endif if (doflocks && tvc->flockCount != 0) { /* if this entry has an flock, send a keep-alive call out */ osi_vnhold(tvc, 0); @@ -1103,8 +1170,13 @@ afs_FlushActiveVcaches(register afs_int32 doflocks) AFS_STATS_FS_RPCIDX_EXTENDLOCK, SHARED_LOCK, NULL)); ReleaseWriteLock(&tvc->lock); +#ifdef AFS_DARWIN80_ENV + AFS_FAST_RELE(tvc); + ObtainReadLock(&afs_xvcache); +#else ObtainReadLock(&afs_xvcache); AFS_FAST_RELE(tvc); +#endif } didCore = 0; if ((tvc->states & CCore) || (tvc->states & CUnlinkedDel)) { @@ -1122,7 +1194,7 @@ afs_FlushActiveVcaches(register afs_int32 doflocks) /* * That's because if we come in via the CUnlinkedDel bit state path we'll be have 0 refcnt */ - osi_Assert(VREFCOUNT(tvc) > 0); + osi_Assert(VREFCOUNT_GT(tvc,0)); AFS_RWLOCK((vnode_t *) tvc, VRWLOCK_WRITE); #endif ObtainWriteLock(&tvc->lock, 52); @@ -1172,6 +1244,15 @@ afs_FlushActiveVcaches(register afs_int32 doflocks) #if defined(AFS_SGI_ENV) AFS_RWUNLOCK((vnode_t *) tvc, VRWLOCK_WRITE); #endif +#ifdef AFS_DARWIN80_ENV + AFS_FAST_RELE(tvc); + if (didCore) { + AFS_RELE(AFSTOV(tvc)); + /* Matches write code setting CCore flag */ + crfree(cred); + } + ObtainReadLock(&afs_xvcache); +#else ObtainReadLock(&afs_xvcache); AFS_FAST_RELE(tvc); if (didCore) { @@ -1179,6 +1260,7 @@ afs_FlushActiveVcaches(register afs_int32 doflocks) /* Matches write code setting CCore flag */ crfree(cred); } +#endif } } } @@ -1623,10 +1705,10 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq, goto loop; #endif } - if (tvc) { if (cached) *cached = 1; + osi_Assert((tvc->states & CVInit) == 0); if (tvc->states & CStatd) { ReleaseSharedLock(&afs_xvcache); return tvc; @@ -1656,6 +1738,10 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq, return tvc; } #endif /* AFS_OSF_ENV */ +#ifdef AFS_DARWIN80_ENV +/* Darwin 8.0 only has bufs in nfs, so we shouldn't have to worry about them. + What about ubc? */ +#else #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) /* * XXX - I really don't like this. Should try to understand better. @@ -1716,6 +1802,7 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq, VOP_UNLOCK(vp, 0, curproc); #endif } +#endif #endif ObtainWriteLock(&afs_xcbhash, 464); @@ -1767,9 +1854,7 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq, if (code) { ReleaseWriteLock(&tvc->lock); - ObtainReadLock(&afs_xvcache); - AFS_FAST_RELE(tvc); - ReleaseReadLock(&afs_xvcache); + afs_PutVCache(tvc); return NULL; } @@ -1826,8 +1911,8 @@ afs_LookupVCache(struct VenusFid *afid, struct vrequest *areq, tvc->states &= ~CUnique; ReleaseReadLock(&tvc->lock); + afs_PutVCache(tvc); ObtainReadLock(&afs_xvcache); - AFS_FAST_RELE(tvc); } /* if (tvc) */ ReleaseReadLock(&afs_xvcache); @@ -1899,9 +1984,7 @@ afs_LookupVCache(struct VenusFid *afid, struct vrequest *areq, if (tvp) afs_PutVolume(tvp, READ_LOCK); ReleaseWriteLock(&tvc->lock); - ObtainReadLock(&afs_xvcache); - AFS_FAST_RELE(tvc); - ReleaseReadLock(&afs_xvcache); + afs_PutVCache(tvc); return NULL; } @@ -1986,10 +2069,17 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq, afid->Fid.Unique = tvolp->rootUnique; } +rootvc_loop: ObtainSharedLock(&afs_xvcache, 7); i = VCHash(afid); for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) { + if (!FidCmp(&(tvc->fid), afid)) { + if (tvc->states & CVInit) { + ReleaseSharedLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + goto rootvc_loop; + } #ifdef AFS_OSF_ENV /* Grab this vnode, possibly reactivating from the free list */ /* for the present (95.05.25) everything on the hash table is @@ -2002,6 +2092,19 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq, if (vg) continue; #endif /* AFS_OSF_ENV */ +#ifdef AFS_DARWIN80_ENV + int vg; + if (tvc->states & CDeadVnode) { + ReleaseSharedLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + goto rootvc_loop; + } + AFS_GUNLOCK(); + vg = vnode_get(AFSTOV(tvc)); /* this bumps ref count */ + AFS_GLOCK(); + if (vg) + continue; +#endif break; } } @@ -2012,9 +2115,13 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq, if (tvc) AFS_RELE(AFSTOV(tvc)); #endif - tvc = NULL; getNewFid = 1; ReleaseSharedLock(&afs_xvcache); +#ifdef AFS_DARWIN80_ENV + if (tvc) + vnode_put(AFSTOV(tvc)); +#endif + tvc = NULL; goto newmtpt; } @@ -2115,9 +2222,7 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq, if ((tvc->states & CForeign) || (tvc->fid.Fid.Vnode & 1)) osi_dnlc_purgedp(tvc); /* if it (could be) a directory */ ReleaseWriteLock(&tvc->lock); - ObtainReadLock(&afs_xvcache); - AFS_FAST_RELE(tvc); - ReleaseReadLock(&afs_xvcache); + afs_PutVCache(tvc); return NULL; } @@ -2396,12 +2501,17 @@ void afs_PutVCache(register struct vcache *avc) { AFS_STATCNT(afs_PutVCache); +#ifdef AFS_DARWIN80_ENV + vnode_put(AFSTOV(avc)); + AFS_FAST_RELE(avc); +#else /* * Can we use a read lock here? */ ObtainReadLock(&afs_xvcache); AFS_FAST_RELE(avc); ReleaseReadLock(&afs_xvcache); +#endif } /*afs_PutVCache */ /* @@ -2431,10 +2541,24 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag) afs_int32 i; AFS_STATCNT(afs_FindVCache); - +findloop: i = VCHash(afid); for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) { if (FidMatches(afid, tvc)) { + if (tvc->states & CVInit) { + int lock; + lock = CheckLock(&afs_xvcache); + if (lock > 0) + ReleaseReadLock(&afs_xvcache); + else + ReleaseSharedLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + if (lock > 0) + ObtainReadLock(&afs_xvcache); + else + ObtainSharedLock(&afs_xvcache, 341); + goto findloop; + } #ifdef AFS_OSF_ENV /* Grab this vnode, possibly reactivating from the free list */ int vg; @@ -2444,6 +2568,28 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag) if (vg) continue; #endif /* AFS_OSF_ENV */ +#ifdef AFS_DARWIN80_ENV + int vg; + if (tvc->states & CDeadVnode) { + int lock; + lock = CheckLock(&afs_xvcache); + if (lock > 0) + ReleaseReadLock(&afs_xvcache); + else + ReleaseSharedLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + if (lock > 0) + ObtainReadLock(&afs_xvcache); + else + ObtainSharedLock(&afs_xvcache, 341); + goto findloop; + } + AFS_GUNLOCK(); + vg = vnode_get(AFSTOV(tvc)); + AFS_GLOCK(); + if (vg) + continue; +#endif break; } } @@ -2457,7 +2603,7 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag) if (retry && *retry) return 0; #endif -#ifdef AFS_DARWIN_ENV +#if defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN80_ENV) tvc->states |= CUBCinit; AFS_GUNLOCK(); if (UBCINFOMISSING(AFSTOV(tvc)) || @@ -2546,9 +2692,7 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid) AFS_STATCNT(afs_FindVCache); -#if defined(AFS_SGI_ENV) && !defined(AFS_SGI53_ENV) loop: -#endif ObtainSharedLock(&afs_xvcache, 331); @@ -2559,6 +2703,12 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid) && (tvc->fid.Fid.Volume == afid->Fid.Volume) && ((tvc->fid.Fid.Unique & 0xffffff) == afid->Fid.Unique) && (tvc->fid.Cell == afid->Cell)) { + if (tvc->states & CVInit) { + int lock; + ReleaseSharedLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + goto loop; + } #ifdef AFS_OSF_ENV /* Grab this vnode, possibly reactivating from the free list */ int vg; @@ -2570,6 +2720,21 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid) continue; } #endif /* AFS_OSF_ENV */ +#ifdef AFS_DARWIN80_ENV + int vg; + if (tvc->states & CDeadVnode) { + ReleaseSharedLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + goto loop; + } + AFS_GUNLOCK(); + vg = vnode_get(AFSTOV(tvc)); + AFS_GLOCK(); + if (vg) { + /* This vnode no longer exists. */ + continue; + } +#endif /* AFS_DARWIN80_ENV */ count++; if (found_tvc) { /* Duplicates */ @@ -2580,6 +2745,11 @@ afs_NFSFindVCache(struct vcache **avcp, struct VenusFid *afid) #endif afs_duplicate_nfs_fids++; ReleaseSharedLock(&afs_xvcache); +#ifdef AFS_DARWIN80_ENV + /* Drop our reference counts. */ + vnode_put(AFSTOV(tvc)); + vnode_put(AFSTOV(found_tvc)); +#endif return count; } found_tvc = tvc; @@ -2770,7 +2940,7 @@ shutdown_vcache(void) vms_delete(tvc->segid); AFS_GLOCK(); tvc->segid = tvc->vmh = NULL; - if (VREFCOUNT(tvc)) + if (VREFCOUNT_GT(tvc,0)) osi_Panic("flushVcache: vm race"); } if (tvc->credp) { diff --git a/src/afs/afs_volume.c b/src/afs/afs_volume.c index d89c8cd41..727812994 100644 --- a/src/afs/afs_volume.c +++ b/src/afs/afs_volume.c @@ -284,6 +284,7 @@ afs_CheckVolumeNames(int flags) /* next ensure all mt points are re-evaluated */ if (nvols || (flags & (AFS_VOLCHECK_FORCE | AFS_VOLCHECK_MTPTS))) { +loop: ObtainReadLock(&afs_xvcache); for (i = 0; i < VCSIZE; i++) { for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) { @@ -306,6 +307,18 @@ afs_CheckVolumeNames(int flags) && (inVolList(&tvc->fid, nvols, volumeID, cellID) || (flags & AFS_VOLCHECK_FORCE))) { + if (tvc->states & CVInit) { + ReleaseReadLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + goto loop; + } +#ifdef AFS_DARWIN80_ENV + if (tvc->states & CDeadVnode) { + ReleaseReadLock(&afs_xvcache); + afs_osi_Sleep(&tvc->states); + goto loop; + } +#endif AFS_FAST_HOLD(tvc); ReleaseReadLock(&afs_xvcache); @@ -317,10 +330,16 @@ afs_CheckVolumeNames(int flags) if (tvc->fid.Fid.Vnode & 1 || (vType(tvc) == VDIR)) osi_dnlc_purgedp(tvc); +#ifdef AFS_DARWIN80_ENV + /* our tvc ptr is still good until now */ + AFS_FAST_RELE(tvc); + ObtainReadLock(&afs_xvcache); +#else ObtainReadLock(&afs_xvcache); /* our tvc ptr is still good until now */ AFS_FAST_RELE(tvc); +#endif } } } diff --git a/src/afs/lock.h b/src/afs/lock.h index a5d8253d7..80e3b7923 100644 --- a/src/afs/lock.h +++ b/src/afs/lock.h @@ -107,7 +107,11 @@ extern tid_t thread_self(); #define MyPidxx current->pid #else #if defined(AFS_DARWIN_ENV) +#if defined(AFS_DARWIN80_ENV) +#define MyPidxx (proc_selfpid()) +#else #define MyPidxx (current_proc()->p_pid ) +#endif #else #if defined(AFS_FBSD_ENV) #define MyPidxx (curproc->p_pid ) diff --git a/src/afs/sysincludes.h b/src/afs/sysincludes.h index 20f876b47..cb7fe5cd0 100644 --- a/src/afs/sysincludes.h +++ b/src/afs/sysincludes.h @@ -219,7 +219,7 @@ typedef unsigned short etap_event_t; # include "h/dir.h" #endif /* SGI || SUN || HPUX */ -#if !defined(AFS_SGI64_ENV) && !defined(AFS_FBSD_ENV) +#if !defined(AFS_SGI64_ENV) && !defined(AFS_FBSD_ENV) && !defined(AFS_DARWIN80_ENV) #include "h/user.h" #endif /* AFS_SGI64_ENV */ #define MACH_USER_API 1 @@ -256,6 +256,10 @@ struct vop_getwritemount_args; # include # include # include +#ifdef AFS_DARWIN80_ENV +# include +#include +#endif # include # include # include @@ -276,9 +280,11 @@ MALLOC_DECLARE(M_AFS); #undef timeout_fcn_t #define _DIR_H_ #define doff_t int32_t +#ifndef AFS_DARWIN80_ENV # include # include # include +#endif #else # include "h/vfs.h" # include "h/vnode.h" diff --git a/src/afsd/afsd.c b/src/afsd/afsd.c index 84debcf20..e22bc6c8a 100644 --- a/src/afsd/afsd.c +++ b/src/afsd/afsd.c @@ -154,6 +154,9 @@ void set_staticaddrs(void); #include #endif #ifdef AFS_DARWIN_ENV +#ifdef AFS_DARWIN80_ENV +#include +#endif #include /* Symbols from the DiskArbitration framework */ kern_return_t DiskArbStart(mach_port_t *); @@ -1860,8 +1863,10 @@ mainproc(struct cmd_syndesc *as, char *arock) #endif code = call_syscall(AFSOP_BASIC_INIT, 1); - if (code) + if (code) { printf("%s: Error %d in basic initialization.\n", rn, code); + exit(1); + } /* * Tell the kernel some basic information about the workstation's cache. @@ -2383,9 +2388,29 @@ call_syscall(param1, param2, param3, param4, param5, param6, param7) close(fd); } else #endif +#ifdef AFS_DARWIN80_ENV + struct afssysargs syscall_data; + int fd = open(SYSCALL_DEV_FNAME,O_RDWR); + syscall_data.syscall = AFSCALL_CALL; + syscall_data.param1 = param1; + syscall_data.param2 = param2; + syscall_data.param3 = param3; + syscall_data.param4 = param4; + syscall_data.param5 = param5; + syscall_data.param6 = param6; + if(fd >= 0) { + error = ioctl(fd, VIOC_SYSCALL, &syscall_data); + close(fd); + } else { + error = -1; + } + if (!error) + error=syscall_data.retval; +#else error = syscall(AFS_SYSCALL, AFSCALL_CALL, param1, param2, param3, param4, param5, param6, param7); +#endif if (afsd_verbose) printf("SScall(%d, %d, %d)=%d ", AFS_SYSCALL, AFSCALL_CALL, param1, diff --git a/src/config/afs_args.h b/src/config/afs_args.h index 7f969c38f..7860e7794 100644 --- a/src/config/afs_args.h +++ b/src/config/afs_args.h @@ -211,5 +211,20 @@ struct afsprocdata32 { #endif +#ifdef AFS_DARWIN80_ENV +struct afssysargs { + unsigned long syscall; + unsigned long param1; + unsigned long param2; + unsigned long param3; + unsigned long param4; + unsigned long param5; + unsigned long param6; + unsigned long retval; +}; +#define VIOC_SYSCALL_TYPE 'C' +#define VIOC_SYSCALL _IOWR(VIOC_SYSCALL_TYPE,1,struct afssysargs) +#define SYSCALL_DEV_FNAME "/dev/openafs_ioctl" +#endif #endif /* _AFS_ARGS_H_ */ diff --git a/src/config/param.ppc_darwin_80.h b/src/config/param.ppc_darwin_80.h index 5ef26e555..b08ddd99a 100644 --- a/src/config/param.ppc_darwin_80.h +++ b/src/config/param.ppc_darwin_80.h @@ -40,7 +40,7 @@ #define AFSBIG_ENDIAN 1 #define AFS_HAVE_FFS 1 /* Use system's ffs. */ -#define AFS_GCPAGS 1 /* if nonzero, garbage collect PAGs */ +#define AFS_GCPAGS 0 #define RXK_LISTENER_ENV 1 #ifdef KERNEL @@ -58,8 +58,8 @@ #define AFS_UIOUSER UIO_USERSPACE #define AFS_CLBYTES CLBYTES #define osi_GetTime(x) microtime(x) -#define AFS_KALLOC(x) kalloc(x) -#define AFS_KFREE(x,y) kfree(x,y) +#define AFS_KALLOC(x) _MALLOC(x, M_TEMP, M_WAITOK) +#define AFS_KFREE(x,y) _FREE(x,M_TEMP) #define v_count v_usecount #define v_vfsp v_mount #define vfs_bsize mnt_stat.f_bsize @@ -67,10 +67,7 @@ #define va_nodeid va_fileid #define vfs_vnodecovered mnt_vnodecovered #define direct dirent -#define vnode_t struct vnode -//#define VN_RELE(vp) vrele(((struct vnode *)(vp))) -//#define VN_HOLD(vp) VREF(((struct vnode *)(vp))) #define BIND_8_COMPAT #endif diff --git a/src/dir/dir.c b/src/dir/dir.c index 252a71717..b7f40a337 100644 --- a/src/dir/dir.c +++ b/src/dir/dir.c @@ -32,7 +32,7 @@ RCSID #include "h/kernel.h" #endif #endif -#if defined(AFS_SUN56_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_SUN56_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_FBSD_ENV) || defined(AFS_DARWIN80_ENV) #include "afs/sysincludes.h" #endif #if !defined(AFS_SGI64_ENV) && !defined(AFS_DARWIN60_ENV) diff --git a/src/libafs/MakefileProto.DARWIN.in b/src/libafs/MakefileProto.DARWIN.in index 20ecf6c21..86603586e 100644 --- a/src/libafs/MakefileProto.DARWIN.in +++ b/src/libafs/MakefileProto.DARWIN.in @@ -33,6 +33,11 @@ AFS_OS_NONFSOBJS = osi_vfsops.o KDEFS= DBUG = DEFINES= -D_KERNEL -DKERNEL -DKERNEL_PRIVATE -DDIAGNOSTIC -DUSE_SELECT -DMACH_USER_API -DMACH_KERNEL + +KOPTS=-static -g -nostdinc -nostdlib -no-cpp-precomp -fno-builtin -finline -fno-keep-inline-functions -msoft-float -mlong-branch -fsigned-bitfields -arch ppc -Dppc -DPPC -D__PPC__ -DPAGE_SIZE_FIXED -O2 -mcpu=750 -mmultiple -fschedule-insns +MODLD=$(CC) $(KOPTS) + +MODLD=$(LD) KOPTS=-static -fno-common -finline -fno-keep-inline-functions -force_cpusubtype_ALL -msoft-float -mlong-branch @@ -41,7 +46,7 @@ KOPTS=-no-cpp-precomp -static -fno-common -finline -fno-keep-inline-functions -f KOPTS=-no-precomp -static -fno-common -finline -fno-keep-inline-functions -force_cpusubtype_ALL -msoft-float -mlong-branch CFLAGS=${KINCLUDES} -I. -I.. -I${TOP_OBJDIR}/src/config $(DEFINES) $(KDEFS) $(KOPTS) ${DBUG} ${OPTMZ} -KINCLUDES=-I${KROOT}/System/Library/Frameworks/Kernel.Framework/Headers +KINCLUDES=-I${KROOT}/System/Library/Frameworks/Kernel.framework/Headers # Name of directory to hold object files and libraries. @@ -60,15 +65,9 @@ setup: ln -fs ../Makefile $(KOBJ)/Makefile ln -fs ../Makefile.common $(KOBJ)/Makefile.common ln -fs ../config $(KOBJ)/config - -$(RM) -f h net netinet rpc ufs nfs machine sys vm mach kern - -ln -fs $(KROOT)/System/Library/Frameworks/Kernel.framework/Headers/net net - -ln -fs $(KROOT)/System/Library/Frameworks/Kernel.framework/Headers/machine machine - -ln -fs $(KROOT)/System/Library/Frameworks/Kernel.framework/Headers/netinet netinet - -ln -fs $(KROOT)/System/Library/Frameworks/Kernel.framework/Headers/nfs nfs - -ln -fs /usr/include/rpc rpc - -ln -fs $(KROOT)/System/Library/Frameworks/Kernel.framework/Headers/sys sys - -ln -fs $(KROOT)/System/Library/Frameworks/Kernel.framework/Headers/ufs ufs + -$(RM) -f h rpc -ln -fs $(KROOT)/System/Library/Frameworks/Kernel.framework/Headers/sys h + -ln -fs /usr/include/rpc rpc # Below this line are targets when in the COMMON directory: @@ -98,7 +97,7 @@ dest_libafs: $(LIBAFSNONFS) ; ${LIBAFS}: $(AFSAOBJS) $(AFSNFSOBJS) - $(LD) -r -o ${LIBAFS} ${AFSAOBJS} ${AFSNFSOBJS} -lcc_kext + $(MODLD) -r -o ${LIBAFS} ${AFSAOBJS} ${AFSNFSOBJS} -lcc_kext ${LIBAFSNONFS}: $(AFSAOBJS) $(AFSNONFSOBJS) - $(LD) -r -o ${LIBAFSNONFS} ${AFSAOBJS} ${AFSNONFSOBJS} -lcc_kext + $(MODLD) -r -o ${LIBAFSNONFS} ${AFSAOBJS} ${AFSNONFSOBJS} -lcc_kext diff --git a/src/libafs/afs.ppc_darwin_80.plist.in b/src/libafs/afs.ppc_darwin_80.plist.in index 0383e3e82..08938589b 100644 --- a/src/libafs/afs.ppc_darwin_80.plist.in +++ b/src/libafs/afs.ppc_darwin_80.plist.in @@ -22,10 +22,12 @@ 1.3.82 OSBundleLibraries - com.apple.kernel.bsd + com.apple.kpi.bsd 8.0.0 - com.apple.kernel.mach + com.apple.kpi.mach 8.0.0 + com.apple.kpi.libkern + 8.0 diff --git a/src/packaging/MacOS/ReadMe.rtf b/src/packaging/MacOS/ReadMe.rtf index 29497b477..00fbab858 100644 --- a/src/packaging/MacOS/ReadMe.rtf +++ b/src/packaging/MacOS/ReadMe.rtf @@ -1,13 +1,13 @@ -{\rtf1\mac\ansicpg10000\cocoartf102 +{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf100 {\fonttbl\f0\fswiss\fcharset77 Helvetica;} {\colortbl;\red255\green255\blue255;} \margl1440\margr1440\vieww9000\viewh9000\viewkind0 \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f0\fs20 \cf0 This release of OpenAFS is known to be compatible with MacOS 10.3 through 10.3.8.\ +\f0\fs20 \cf0 This pre-release of OpenAFS is targeted at MacOS 10.4.1. It is *not* production ready. Use of this release with afs home directories or Library directories is not recommended. (keychain corruption may occur. keychain-using apps may hang). afssettings does not work either. unmount afs manually before rebooting/shutting down, or the shutdown will not complete. \ \ Select a client cell name by editing /var/db/openafs/etc/ThisCell\ \ The included afssettings program is distributed under the Apple Public Source License, version 2.0. See http://www.opensource.apple.com/apsl/2.0.txt or the included file 2.0.txt.\ \ -Reboot when all of this is done.} \ No newline at end of file +Reboot when all of this is done.} diff --git a/src/packaging/MacOS/buildpkg.sh b/src/packaging/MacOS/buildpkg.sh index 7c617c55e..f2774bfea 100644 --- a/src/packaging/MacOS/buildpkg.sh +++ b/src/packaging/MacOS/buildpkg.sh @@ -32,7 +32,8 @@ else fi if [ -x /usr/bin/curl ]; then - /usr/bin/curl -f -O http://www.central.org/dl/cellservdb/CellServDB +# /usr/bin/curl -f -O http://www.central.org/dl/cellservdb/CellServDB + /usr/bin/curl -f -O http://dl.central.org/dl/cellservdb/CellServDB fi if [ ! -f CellServDB ]; then @@ -82,6 +83,8 @@ cp $BINDEST/root.client/usr/vice/etc/StartupParameters.plist $PKGROOT/Library/S chown -R root${SEP}admin $PKGROOT/Library chmod -R o-w $PKGROOT/Library chmod -R g+w $PKGROOT/Library +chown -R root${SEP}wheel $PKGROOT/Library/StartupItems +chmod -R og-w $PKGROOT/Library/StartupItems chown -R root${SEP}wheel $PKGROOT/Library/OpenAFS/Tools chmod -R og-w $PKGROOT/Library/OpenAFS/Tools @@ -111,7 +114,7 @@ chmod og-rx $PKGROOT/private/var/db/openafs/cache mkdir $PKGROOT/usr $PKGROOT/usr/bin $PKGROOT/usr/sbin -BINLIST="fs klog klog.krb pagsh pagsh.krb pts sys tokens tokens.krb unlog unlog.krb" +BINLIST="fs klog klog.krb pagsh pagsh.krb pts sys tokens tokens.krb unlog unlog.krb aklog" # Should these be linked into /usr too? OTHER_BINLIST="bos cmdebug rxgen translate_et udebug xstat_cm_test xstat_fs_test" @@ -131,7 +134,10 @@ if [ $majorvers -ge 7 ]; then cp OpenAFS.post_install $PKGRES/postinstall cp OpenAFS.pre_upgrade $PKGRES/preupgrade cp OpenAFS.post_install $PKGRES/postupgrade - chmod a+x $PKGRES/postinstall $PKGRES/postupgrade $PKGRES/preupgrade + cp InstallationCheck $PKGRES + mkdir $PKGRES/English.lproj + cp InstallationCheck $PKGRES/English.lproj + chmod a+x $PKGRES/postinstall $PKGRES/postupgrade $PKGRES/preupgrade $PKGRES/InstallationCheck else cp OpenAFS.post_install OpenAFS.pre_upgrade $PKGRES cp OpenAFS.post_install $PKGRES/OpenAFS.post_upgrade diff --git a/src/rx/DARWIN/rx_kmutex.c b/src/rx/DARWIN/rx_kmutex.c index f4c7f7bb3..98f9ba4c8 100644 --- a/src/rx/DARWIN/rx_kmutex.c +++ b/src/rx/DARWIN/rx_kmutex.c @@ -19,6 +19,34 @@ RCSID ("$Header$"); +#ifndef AFS_DARWIN80_ENV /* * Currently everything is implemented in rx_kmutex.h */ +#else +#include /* Standard vendor system headers */ +#include /* Afs-based standard headers */ +#include /* statistics */ +#include +#include +#include +#if defined(AFS_DARWIN70_ENV) +#include +#endif /* defined(AFS_DARWIN70_ENV) */ + +lck_grp_t * openafs_lck_grp; +static lck_grp_attr_t * openafs_lck_grp_attr; +void rx_kmutex_setup(void) { + openafs_lck_grp_attr= lck_grp_attr_alloc_init(); + lck_grp_attr_setstat(openafs_lck_grp_attr); + + openafs_lck_grp = lck_grp_alloc_init("openafs", openafs_lck_grp_attr); + lck_grp_attr_free(openafs_lck_grp_attr); + +} + +void rx_kmutex_finish(void) { + lck_grp_free(openafs_lck_grp); +} + +#endif diff --git a/src/rx/DARWIN/rx_kmutex.h b/src/rx/DARWIN/rx_kmutex.h index 563c3a2a1..07fb0246f 100644 --- a/src/rx/DARWIN/rx_kmutex.h +++ b/src/rx/DARWIN/rx_kmutex.h @@ -16,7 +16,11 @@ #ifndef _RX_KMUTEX_H_ #define _RX_KMUTEX_H_ +#ifdef AFS_DARWIN80_ENV +#include +#else #include +#endif #include #include @@ -32,30 +36,48 @@ * * XXX in darwin, both mach and bsd facilities are available. Should really * stick to one or the other (but mach locks don't have a _try.....) + * + * in darwin 8.0, the bsd lock facility is no longer available, and only one + * sleep variant is available. Still no lock_try, but we can work around that. + * We can't pass the mutex into msleep, even if we didn't need the two mutex + * hack for lock_try emulation, since msleep won't fixup the owner variable + * and we'll panic. */ #define CV_INIT(cv,a,b,c) #define CV_DESTROY(cv) #ifdef AFS_DARWIN14_ENV -#define CV_WAIT(cv, lck) { \ +#ifdef AFS_DARWIN80_ENV +#define VFSSLEEP(cv) msleep(cv, NULL, PVFS, "afs_CV_WAIT", NULL) +#define VFSTSLEEP(cv,t) do { \ + struct timespec ts; \ + ts.ts_sec = t; \ + ts.ts_nsec = 0; \ + msleep(cv, NULL, PVFS, "afs_CV_TIMEDWAIT", &ts); \ +} while(0) +#else +#define VFSSLEEP(cv) sleep(cv, PVFS) +#define VFSTSLEEP(cv, t) tsleep(cv,PVFS, "afs_CV_TIMEDWAIT",t) +#endif +#define CV_WAIT(cv, lck) do { \ int isGlockOwner = ISAFS_GLOCK(); \ if (isGlockOwner) AFS_GUNLOCK(); \ MUTEX_EXIT(lck); \ - sleep(cv, PVFS); \ + VFSSLEEP(cv); \ if (isGlockOwner) AFS_GLOCK(); \ MUTEX_ENTER(lck); \ - } + } while(0) -#define CV_TIMEDWAIT(cv,lck,t) { \ +#define CV_TIMEDWAIT(cv,lck,t) do { \ int isGlockOwner = ISAFS_GLOCK(); \ if (isGlockOwner) AFS_GUNLOCK(); \ MUTEX_EXIT(lck); \ - tsleep(cv,PVFS, "afs_CV_TIMEDWAIT",t); \ + VFSTSLEEP(cv,t); \ if (isGlockOwner) AFS_GLOCK(); \ MUTEX_ENTER(lck); \ - } + } while(0) -#define CV_SIGNAL(cv) wakeup_one(cv) -#define CV_BROADCAST(cv) wakeup(cv) +#define CV_SIGNAL(cv) wakeup_one((void *)(cv)) +#define CV_BROADCAST(cv) wakeup((void *)(cv)) #else #define CV_WAIT(cv, lck) { \ int isGlockOwner = ISAFS_GLOCK(); \ @@ -82,13 +104,86 @@ #define CV_BROADCAST(cv) thread_wakeup((event_t)(cv)) #endif +#ifdef AFS_DARWIN80_ENV typedef struct { - struct lock__bsd__ lock; + lck_mtx_t *meta; + int waiters; /* also includes anyone holding the lock */ + lck_mtx_t *lock; thread_t owner; } afs_kmutex_t; typedef int afs_kcondvar_t; -#define osi_rxWakeup(cv) thread_wakeup((event_t)(cv)) +extern lck_grp_t * openafs_lck_grp; + +#define MUTEX_SETUP() rx_kmutex_setup() +#define MUTEX_FINISH() rx_kmutex_finish() +#define LOCKINIT(a) \ + do { \ + lck_attr_t *openafs_lck_attr = lck_attr_alloc_init(); \ + (a) = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \ + lck_attr_free(openafs_lck_attr); \ + } while(0) +#define MUTEX_INIT(a,b,c,d) \ + do { \ + lck_attr_t *openafs_lck_attr = lck_attr_alloc_init(); \ + (a)->meta = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \ + (a)->lock = lck_mtx_alloc_init(openafs_lck_grp, openafs_lck_attr); \ + lck_attr_free(openafs_lck_attr); \ + (a)->waiters = 0; \ + (a)->owner = (thread_t)0; \ + } while(0) +#define MUTEX_DESTROY(a) \ + do { \ + lck_mtx_destroy((a)->lock, openafs_lck_grp); \ + lck_mtx_destroy((a)->meta, openafs_lck_grp); \ + (a)->owner = (thread_t)-1; \ + } while(0) +#define MUTEX_ENTER(a) \ + do { \ + lck_mtx_lock((a)->meta); \ + (a)->waiters++; \ + lck_mtx_unlock((a)->meta); \ + lck_mtx_lock((a)->lock); \ + osi_Assert((a)->owner == (thread_t)0); \ + (a)->owner = current_thread(); \ + } while(0) + +/* acquire main lock before releasing meta lock, so we don't race */ +#define MUTEX_TRYENTER(a) ({ \ + int _ret; \ + lck_mtx_lock((a)->meta); \ + if ((a)->waiters) { \ + lck_mtx_unlock((a)->meta); \ + _ret = 0; \ + } else { \ + (a)->waiters++; \ + lck_mtx_lock((a)->lock); \ + lck_mtx_unlock((a)->meta); \ + osi_Assert((a)->owner == (thread_t)0); \ + (a)->owner = current_thread(); \ + _ret = 1; \ + } \ + _ret; \ +}) + +#define MUTEX_EXIT(a) \ + do { \ + osi_Assert((a)->owner == current_thread()); \ + (a)->owner = (thread_t)0; \ + lck_mtx_unlock((a)->lock); \ + lck_mtx_lock((a)->meta); \ + (a)->waiters--; \ + lck_mtx_unlock((a)->meta); \ + } while(0) + +#undef MUTEX_ISMINE +#define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == current_thread()) +#else +typedef struct { + struct lock__bsd__ lock; + thread_t owner; +} afs_kmutex_t; +typedef int afs_kcondvar_t; #define LOCK_INIT(a,b) \ do { \ @@ -112,8 +207,6 @@ typedef int afs_kcondvar_t; } while(0); #define MUTEX_TRYENTER(a) \ ( lockmgr(&(a)->lock, LK_EXCLUSIVE|LK_NOWAIT, 0, current_proc()) ? 0 : ((a)->owner = current_thread(), 1) ) -#define xMUTEX_TRYENTER(a) \ - ( osi_Assert((a)->owner == (thread_t)0), (a)->owner = current_thread(), 1) #define MUTEX_EXIT(a) \ do { \ osi_Assert((a)->owner == current_thread()); \ @@ -123,6 +216,7 @@ typedef int afs_kcondvar_t; #undef MUTEX_ISMINE #define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == current_thread()) +#endif #undef osirx_AssertMine extern void osirx_AssertMine(afs_kmutex_t * lockaddr, char *msg); diff --git a/src/rx/DARWIN/rx_knet.c b/src/rx/DARWIN/rx_knet.c index a45381e0a..4422f8118 100644 --- a/src/rx/DARWIN/rx_knet.c +++ b/src/rx/DARWIN/rx_knet.c @@ -15,16 +15,29 @@ RCSID #include "rx/rx_kcommon.h" +#ifdef AFS_DARWIN80_ENV +#define soclose sock_close +#endif + int osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec, int nvecs, int *alength) { +#ifdef AFS_DARWIN80_ENV + socket_t asocket = (socket_t)so; + struct msghdr msg; + struct sockaddr_storage ss; + int rlen; + mbuf_t m; +#else struct socket *asocket = (struct socket *)so; struct uio u; +#endif int i; struct iovec iov[RX_MAXIOVECS]; struct sockaddr *sa = NULL; int code; + size_t resid; int haveGlock = ISAFS_GLOCK(); /*AFS_STATCNT(osi_NetReceive); */ @@ -34,6 +47,59 @@ osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec, for (i = 0; i < nvecs; i++) iov[i] = dvec[i]; + if (haveGlock) + AFS_GUNLOCK(); +#if defined(KERNEL_FUNNEL) + thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); +#endif +#ifdef AFS_DARWIN80_ENV +#if 1 + resid = *alength; + memset(&msg, 0, sizeof(struct msghdr)); + msg.msg_name = &ss; + msg.msg_namelen = sizeof(struct sockaddr_storage); + sa =(struct sockaddr *) &ss; + code = sock_receivembuf(asocket, &msg, &m, 0, alength); + if (!code) { + size_t offset=0,sz; + resid = *alength; + for (i=0;i rlen) + resid -= rlen; + else + resid = 0; +#endif +#else u.uio_iov = &iov[0]; u.uio_iovcnt = nvecs; @@ -42,14 +108,11 @@ osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec, u.uio_segflg = UIO_SYSSPACE; u.uio_rw = UIO_READ; u.uio_procp = NULL; - - if (haveGlock) - AFS_GUNLOCK(); -#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL) - thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); -#endif code = soreceive(asocket, &sa, &u, NULL, NULL, NULL); -#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL) + resid = u.uio_resid; +#endif + +#if defined(KERNEL_FUNNEL) thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); #endif if (haveGlock) @@ -57,7 +120,7 @@ osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec, if (code) return code; - *alength -= u.uio_resid; + *alength -= resid; if (sa) { if (sa->sa_family == AF_INET) { if (addr) @@ -75,26 +138,37 @@ osi_StopListener(void) { struct proc *p; -#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL) +#if defined(KERNEL_FUNNEL) thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); #endif soclose(rx_socket); -#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL) +#if defined(KERNEL_FUNNEL) thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); #endif +#ifdef AFS_DARWIN80_ENV + proc_signal(rxk_ListenerPid, SIGUSR1); +#else p = pfind(rxk_ListenerPid); if (p) psignal(p, SIGUSR1); +#endif } int -osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec, +osi_NetSend(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec, int nvecs, afs_int32 alength, int istack) { +#ifdef AFS_DARWIN80_ENV + socket_t asocket = (socket_t)so; + struct msghdr msg; + size_t slen; +#else + struct socket *asocket = (struct socket *)so; + struct uio u; +#endif register afs_int32 code; int i; struct iovec iov[RX_MAXIOVECS]; - struct uio u; int haveGlock = ISAFS_GLOCK(); AFS_STATCNT(osi_NetSend); @@ -104,6 +178,21 @@ osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec, for (i = 0; i < nvecs; i++) iov[i] = dvec[i]; + addr->sin_len = sizeof(struct sockaddr_in); + + if (haveGlock) + AFS_GUNLOCK(); +#if defined(KERNEL_FUNNEL) + thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); +#endif +#ifdef AFS_DARWIN80_ENV + memset(&msg, 0, sizeof(struct msghdr)); + msg.msg_name = addr; + msg.msg_namelen = ((struct sockaddr *)addr)->sa_len; + msg.msg_iov = &iov[0]; + msg.msg_iovlen = nvecs; + code = sock_send(asocket, &msg, 0, &slen); +#else u.uio_iov = &iov[0]; u.uio_iovcnt = nvecs; u.uio_offset = 0; @@ -111,16 +200,10 @@ osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec, u.uio_segflg = UIO_SYSSPACE; u.uio_rw = UIO_WRITE; u.uio_procp = NULL; - - addr->sin_len = sizeof(struct sockaddr_in); - - if (haveGlock) - AFS_GUNLOCK(); -#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL) - thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); -#endif code = sosend(asocket, (struct sockaddr *)addr, &u, NULL, NULL, 0); -#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL) +#endif + +#if defined(KERNEL_FUNNEL) thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); #endif if (haveGlock) diff --git a/src/rx/UKERNEL/rx_kcommon.h b/src/rx/UKERNEL/rx_kcommon.h index 765d7cea2..a30260f33 100644 --- a/src/rx/UKERNEL/rx_kcommon.h +++ b/src/rx/UKERNEL/rx_kcommon.h @@ -36,4 +36,6 @@ typedef char *rxk_portRocks_t[MAXRXPORTS]; extern rxk_ports_t rxk_ports; extern rxk_portRocks_t rxk_portRocks; +#define ifnet_flags(x) (x?(x)->if_flags:0) + #endif /* _RX_KCOMMON_H_ */ diff --git a/src/rx/rx_kcommon.c b/src/rx/rx_kcommon.c index 66f56913d..d37d93d6f 100644 --- a/src/rx/rx_kcommon.c +++ b/src/rx/rx_kcommon.c @@ -45,6 +45,11 @@ static int myNetMTUs[ADDRSPERSITE]; static int numMyNetAddrs = 0; #endif +#if defined(AFS_DARWIN80_ENV) +#define sobind sock_bind +#define soclose sock_close +#endif + /* add a port to the monitored list, port # is in network order */ static int rxk_AddPort(u_short aport, char *arock) @@ -392,7 +397,11 @@ rxi_InitPeerParams(register struct rx_peer *pp) pp->ifMTU = RX_REMOTE_PACKET_SIZE; } #else /* AFS_USERSPACE_IP_ADDR */ +#ifdef AFS_DARWIN80_ENV + ifnet_t ifn; +#else struct ifnet *ifn; +#endif #if !defined(AFS_SGI62_ENV) if (numMyNetAddrs == 0) @@ -405,7 +414,7 @@ rxi_InitPeerParams(register struct rx_peer *pp) /* pp->timeout.usec = 0; */ pp->ifMTU = MIN(RX_MAX_PACKET_SIZE, rx_MyMaxSendSize); #ifdef IFF_POINTOPOINT - if (ifn->if_flags & IFF_POINTOPOINT) { + if (ifnet_flags(ifn) & IFF_POINTOPOINT) { /* wish we knew the bit rate and the chunk size, sigh. */ pp->timeout.sec = 4; pp->ifMTU = RX_PP_PACKET_SIZE; @@ -413,8 +422,8 @@ rxi_InitPeerParams(register struct rx_peer *pp) #endif /* IFF_POINTOPOINT */ /* Diminish the packet size to one based on the MTU given by * the interface. */ - if (ifn->if_mtu > (RX_IPUDP_SIZE + RX_HEADER_SIZE)) { - rxmtu = ifn->if_mtu - RX_IPUDP_SIZE; + if (ifnet_mtu(ifn) > (RX_IPUDP_SIZE + RX_HEADER_SIZE)) { + rxmtu = ifnet_mtu(ifn) - RX_IPUDP_SIZE; if (rxmtu < pp->ifMTU) pp->ifMTU = rxmtu; } @@ -615,16 +624,53 @@ rxi_GetIFInfo(void) int i = 0; int different = 0; - register struct ifnet *ifn; register int rxmtu, maxmtu; afs_uint32 addrs[ADDRSPERSITE]; int mtus[ADDRSPERSITE]; - struct ifaddr *ifad; /* ifnet points to a if_addrlist of ifaddrs */ afs_uint32 ifinaddr; +#if defined(AFS_DARWIN80_ENV) + errno_t t; + int cnt=0; + ifaddr_t *ifads, ifad; + register ifnet_t ifn; + struct sockaddr sout; + struct sockaddr_in *sin; +#else + struct ifaddr *ifad; /* ifnet points to a if_addrlist of ifaddrs */ + register struct ifnet *ifn; +#endif memset(addrs, 0, sizeof(addrs)); memset(mtus, 0, sizeof(mtus)); +#if defined(AFS_DARWIN80_ENV) + t = ifnet_get_address_list_family(NULL, &ifads, AF_INET); + if (t == 0) { + rxmtu = ifnet_mtu(ifn) - RX_IPUDP_SIZE; + while((ifads[cnt] != NULL) && cnt < ADDRSPERSITE) { + t = ifaddr_address(ifads[cnt], &sout, sizeof(sout)); + sin = (struct sockaddr_in *)&sout; + ifinaddr = ntohl(sin->sin_addr.s_addr); + if (myNetAddrs[i] != ifinaddr) { + different++; + } + mtus[i] = rxmtu; + rxmtu = rxi_AdjustIfMTU(rxmtu); + maxmtu = + rxmtu * rxi_nRecvFrags + + ((rxi_nRecvFrags - 1) * UDP_HDR_SIZE); + maxmtu = rxi_AdjustMaxMTU(rxmtu, maxmtu); + addrs[i++] = ifinaddr; + if ((ifinaddr != 0x7f000001) && (maxmtu > rx_maxReceiveSize)) { + rx_maxReceiveSize = MIN(RX_MAX_PACKET_SIZE, maxmtu); + rx_maxReceiveSize = + MIN(rx_maxReceiveSize, rx_maxReceiveSizeUser); + } + cnt++; + } + ifnet_free_address_list(ifads); + } +#else #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) TAILQ_FOREACH(ifn, &ifnet, if_link) { if (i >= ADDRSPERSITE) @@ -670,6 +716,7 @@ rxi_GetIFInfo(void) } } } +#endif rx_maxJumboRecvSize = RX_HEADER_SIZE + rxi_nDgramPackets * RX_JUMBOBUFFERSIZE + @@ -688,19 +735,39 @@ rxi_GetIFInfo(void) #if defined(AFS_DARWIN60_ENV) || defined(AFS_XBSD_ENV) /* Returns ifnet which best matches address */ +#ifdef AFS_DARWIN80_ENV +ifnet_t +#else struct ifnet * +#endif rxi_FindIfnet(afs_uint32 addr, afs_uint32 * maskp) { - struct sockaddr_in s; + struct sockaddr_in s, sr; +#ifdef AFS_DARWIN80_ENV + ifaddr_t ifad; +#else struct ifaddr *ifad; +#endif s.sin_family = AF_INET; s.sin_addr.s_addr = addr; +#ifdef AFS_DARWIN80_ENV + ifad = ifaddr_withnet((struct sockaddr *)&s); +#else ifad = ifa_ifwithnet((struct sockaddr *)&s); +#endif +#ifdef AFS_DARWIN80_ENV + if (ifad && maskp) { + ifaddr_netmask(ifad, (struct sockaddr *)&sr, sizeof(sr)); + *maskp = sr.sin_addr.s_addr; + } + return (ifad ? ifaddr_ifnet(ifad) : NULL); +#else if (ifad && maskp) *maskp = ((struct sockaddr_in *)ifad->ifa_netmask)->sin_addr.s_addr; return (ifad ? ifad->ifa_ifp : NULL); +#endif } #else /* DARWIN60 || XBSD */ @@ -765,7 +832,11 @@ osi_socket * rxk_NewSocketHost(afs_uint32 ahost, short aport) { register afs_int32 code; +#ifdef AFS_DARWIN80_ENV + socket_t newSocket; +#else struct socket *newSocket; +#endif #if (!defined(AFS_HPUX1122_ENV) && !defined(AFS_FBSD50_ENV)) struct mbuf *nam; #endif @@ -814,6 +885,8 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport) afs_osi_credp, curthread); #elif defined(AFS_FBSD40_ENV) code = socreate(AF_INET, &newSocket, SOCK_DGRAM, IPPROTO_UDP, curproc); +#elif defined(AFS_DARWIN80_ENV) + code = sock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, NULL, &newSocket); #else code = socreate(AF_INET, &newSocket, SOCK_DGRAM, 0); #endif /* AFS_HPUX102_ENV */ @@ -849,12 +922,30 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport) freeb(bindnam); #else /* AFS_HPUX110_ENV */ +#if defined(AFS_DARWIN80_ENV) + { + int buflen = 50000; + int i,code2; + for (i=0;i<2;i++) { + code = sock_setsockopt(newSocket, SOL_SOCKET, SO_SNDBUF, + &buflen, sizeof(buflen)); + code2 = sock_setsockopt(newSocket, SOL_SOCKET, SO_RCVBUF, + &buflen, sizeof(buflen)); + if (!code && !code2) + break; + if (i == 2) + osi_Panic("osi_NewSocket: last attempt to reserve 32K failed!\n"); + buflen = 32766; + } + } +#else code = soreserve(newSocket, 50000, 50000); if (code) { code = soreserve(newSocket, 32766, 32766); if (code) osi_Panic("osi_NewSocket: last attempt to reserve 32K failed!\n"); } +#endif #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) #if defined(AFS_FBSD50_ENV) code = sobind(newSocket, (struct sockaddr *)&myaddr, curthread); @@ -1133,13 +1224,14 @@ rxk_Listener(void) #ifdef AFS_XBSD_ENV rxk_ListenerPid = curproc->p_pid; #endif /* AFS_FBSD_ENV */ -#if defined(AFS_DARWIN_ENV) +#ifdef AFS_DARWIN80_ENV + rxk_ListenerPid = proc_selfpid(); +#elif defined(AFS_DARWIN_ENV) rxk_ListenerPid = current_proc()->p_pid; #endif #if defined(RX_ENABLE_LOCKS) && !defined(AFS_SUN5_ENV) AFS_GUNLOCK(); #endif /* RX_ENABLE_LOCKS && !AFS_SUN5_ENV */ - while (afs_termState != AFSOP_STOP_RXK_LISTENER) { if (rxp) { rxi_RestoreDataBufs(rxp); diff --git a/src/rx/rx_kcommon.h b/src/rx/rx_kcommon.h index 4cc32966d..3015a0114 100644 --- a/src/rx/rx_kcommon.h +++ b/src/rx/rx_kcommon.h @@ -155,6 +155,18 @@ extern rxk_portRocks_t rxk_portRocks; extern struct domain inetdomain; #endif /* AFS_XBSD_ENV */ +#ifndef AFS_DARWIN80_ENV +#define ifaddr_address_family(x) (x)->ifa_addr->sa_family +#define ifaddr_address(x, y, z) memcpy(y, (x)->ifa_addr, z) +#define ifaddr_netmask(x, y, z) memcpy(y, (x)->ifa_netmask, z) +#define ifaddr_dstaddress(x, y, z) memcpy(y, (x)->ifa_dstaddr, z) +#define ifaddr_ifnet(x) (x?(x)->ifa_ifp:0) +#define ifnet_flags(x) (x?(x)->if_flags:0) +#define ifnet_metric(x) (x?(x)->if_data.ifi_metric:0) +/*#define ifnet_mtu(x) (x)->if_mtu*/ +#define ifaddr_withnet(x) ifa_ifwithnet(x) +#endif + #endif /* _RX_KCOMMON_H_ */ #endif diff --git a/src/rx/rx_kernel.h b/src/rx/rx_kernel.h index da3555c4a..d147e3b0a 100644 --- a/src/rx/rx_kernel.h +++ b/src/rx/rx_kernel.h @@ -41,6 +41,13 @@ extern int osi_utoa(char *buf, size_t len, unsigned long val); #define osi_YieldIfPossible() #define osi_WakeupAndYieldIfPossible(x) rx_Wakeup(x) +#ifndef AFS_DARWIN80_ENV +#define ifnet_mtu(x) (x)->if_mtu +#define AFS_IFNET_T struct ifnet * +#else +#define AFS_IFNET_T ifnet_t +#endif + #include "afs/longc_procs.h" #endif /* __RX_KERNEL_INCL_ */ diff --git a/src/rx/rx_packet.c b/src/rx/rx_packet.c index f0a8fe9b1..8769088ed 100644 --- a/src/rx/rx_packet.c +++ b/src/rx/rx_packet.c @@ -1551,7 +1551,7 @@ cpytoiovec(mblk_t * mp, int off, int len, register struct iovec *iovs, #define m_cpytoc(a, b, c, d) cpytoc(a, b, c, d) #define m_cpytoiovec(a, b, c, d, e) cpytoiovec(a, b, c, d, e) #else -#if !defined(AFS_LINUX20_ENV) +#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN80_ENV) static int m_cpytoiovec(struct mbuf *m, int off, int len, struct iovec iovs[], int niovs) { @@ -1607,7 +1607,7 @@ m_cpytoiovec(struct mbuf *m, int off, int len, struct iovec iovs[], int niovs) #endif /* LINUX */ #endif /* AFS_SUN5_ENV */ -#if !defined(AFS_LINUX20_ENV) +#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN80_ENV) int rx_mb_to_packet(amb, free, hdr_len, data_len, phandle) #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX110_ENV) diff --git a/src/rx/rx_prototypes.h b/src/rx/rx_prototypes.h index fd354b9fb..f76b15714 100644 --- a/src/rx/rx_prototypes.h +++ b/src/rx/rx_prototypes.h @@ -348,6 +348,10 @@ extern void rxk_ListenerProc(void); extern void rxk_Listener(void); #ifndef UKERNEL extern void afs_rxevent_daemon(void); +#endif +#if defined(AFS_DARWIN80_ENV) && defined(KERNEL) +extern ifnet_t rxi_FindIfnet(afs_uint32 addr, afs_uint32 * maskp); +#else extern struct ifnet *rxi_FindIfnet(afs_uint32 addr, afs_uint32 * maskp); #endif extern void osi_StopListener(void); diff --git a/src/rx/xdr.c b/src/rx/xdr.c index 469352a51..5816ef162 100644 --- a/src/rx/xdr.c +++ b/src/rx/xdr.c @@ -58,6 +58,7 @@ RCSID #include #endif #include "xdr.h" +#include "rx.h" /* * constants specific to the xdr "protocol" diff --git a/src/rx/xdr_prototypes.h b/src/rx/xdr_prototypes.h index 8d0870eae..5c1898ee3 100644 --- a/src/rx/xdr_prototypes.h +++ b/src/rx/xdr_prototypes.h @@ -10,13 +10,7 @@ #ifndef _XDR_PROTOTYPES_H #define _XDR_PROTOTYPES_H -/* I don't like this, but some of these defs depend on rx.h */ -#if defined(KERNEL) && defined(UKERNEL) -#include "afs/sysincludes.h" -#include "rx/rx.h" -#else -#include "rx/rx.h" -#endif +struct rx_call; /* xdr_afsuuid.c */ extern int xdr_afsUUID(XDR * xdrs, afsUUID * objp); diff --git a/src/sys/afssyscalls.c b/src/sys/afssyscalls.c index 7bb25a9ed..bb50ba3c0 100644 --- a/src/sys/afssyscalls.c +++ b/src/sys/afssyscalls.c @@ -314,7 +314,33 @@ iwrite(int dev, int inode, int inode_p1, unsigned int offset, char *cbuf, #endif /* AFS_NAMEI_ENV */ -#ifdef AFS_LINUX20_ENV +#if defined(AFS_DARWIN80_ENV) +int ioctl_afs_syscall(long syscall, long param1, long param2, long param3, + long param4, long param5, long param6, int *rval) { + struct afssysargs syscall_data; + int code; + int fd = open(SYSCALL_DEV_FNAME, O_RDWR); + if(fd < 0) + return -1; + + syscall_data.syscall = syscall; + syscall_data.param1 = param1; + syscall_data.param2 = param2; + syscall_data.param3 = param3; + syscall_data.param4 = param4; + syscall_data.param5 = param5; + syscall_data.param6 = param6; + + code = ioctl(fd, VIOC_SYSCALL, &syscall_data); + + close(fd); + if (code) + return code; + *rval=syscall_data.retval; + return 0; +} +#endif +#if defined(AFS_LINUX20_ENV) int proc_afs_syscall(long syscall, long param1, long param2, long param3, long param4, int *rval) { struct afsprocdata syscall_data; @@ -343,11 +369,14 @@ lsetpag(void) { int errcode, rval; -#ifdef AFS_LINUX20_ENV +#if defined(AFS_LINUX20_ENV) rval = proc_afs_syscall(AFSCALL_SETPAG,0,0,0,0,&errcode); if(rval) errcode = syscall(AFS_SYSCALL, AFSCALL_SETPAG); +#elif defined(AFS_DARWIN80_ENV) + if (ioctl_afs_syscall(AFSCALL_SETPAG,0,0,0,0,0,0,&errcode)) + errcode=ENOSYS; #else errcode = syscall(AFS_SYSCALL, AFSCALL_SETPAG); #endif @@ -360,11 +389,14 @@ lpioctl(char *path, int cmd, char *cmarg, int follow) { int errcode, rval; -#ifdef AFS_LINUX20_ENV +#if defined(AFS_LINUX20_ENV) rval = proc_afs_syscall(AFSCALL_PIOCTL, (long)path, cmd, (long)cmarg, follow, &errcode); if(rval) errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow); +#elif defined(AFS_DARWIN80_ENV) + if (ioctl_afs_syscall(AFSCALL_PIOCTL,(long)path,cmd,(long)cmarg,follow,0,0,&errcode)) + errcode=ENOSYS; #else errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow); #endif diff --git a/src/venus/fstrace.c b/src/venus/fstrace.c index 27899cc8d..b627fba5c 100644 --- a/src/venus/fstrace.c +++ b/src/venus/fstrace.c @@ -2156,6 +2156,10 @@ afs_syscall(call, parm0, parm1, parm2, parm3, parm4, parm5, parm6) __asm__ __volatile__("mov %o0, %i0; ret; restore"); #endif #else +#ifdef AFS_DARWIN80_ENV + code = ioctl_afs_syscall(call, parm0, parm1, parm2, parm3, parm4, parm5, &rval); + if (!code) code = rval; +#else #if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV) code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, parm3, parm4); #else @@ -2165,6 +2169,7 @@ afs_syscall(call, parm0, parm1, parm2, parm3, parm4, parm5, parm6) code = syscall(AFSCALL_ICL, parm0, parm1, parm2, parm3, parm4); #endif #endif +#endif #endif /* AFS_LINUX20_ENV */ return code; } -- 2.39.5