diff --git a/src/afs/DARWIN/osi_file.c b/src/afs/DARWIN/osi_file.c index 3605620e76..9b05020e19 100644 --- a/src/afs/DARWIN/osi_file.c +++ b/src/afs/DARWIN/osi_file.c @@ -33,7 +33,7 @@ afs_InitDualFSCacheOps(struct vnode *vp) int code; static int inited = 0; #ifdef AFS_DARWIN80_ENV - char *buffer = (char*)malloc(MFSNAMELEN); + char *buffer = (char*)_MALLOC(MFSNAMELEN, M_TEMP, M_WAITOK); #endif if (inited) @@ -58,7 +58,7 @@ afs_InitDualFSCacheOps(struct vnode *vp) else osi_Panic("Unknown cache vnode type\n"); #ifdef AFS_DARWIN80_ENV - free(buffer); + _FREE(buffer, M_TEMP); #endif } @@ -77,7 +77,16 @@ VnodeToIno(vnode_t * avp) ret = ip->i_number; } else if (afs_CacheFSType == AFS_APPL_HFS_CACHE) { #endif -#if !defined(AFS_DARWIN80_ENV) && !defined(VTOH) +#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"); @@ -107,7 +116,16 @@ VnodeToDev(vnode_t * avp) return ip->i_dev; } else if (afs_CacheFSType == AFS_APPL_HFS_CACHE) { #endif -#if !defined(AFS_DARWIN80_ENV) && !defined(VTOH) +#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"); @@ -125,13 +143,8 @@ VnodeToDev(vnode_t * avp) void * osi_UFSOpen(afs_int32 ainode) { -#ifdef AFS_DARWIN80_ENV - vnode_t vp; - struct vattr va; -#else struct vnode *vp; struct vattr va; -#endif register struct osi_file *afile = NULL; extern int cacheDiskType; afs_int32 code = 0; @@ -149,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); @@ -178,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; @@ -195,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); @@ -219,10 +251,16 @@ 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; @@ -237,13 +275,10 @@ osi_DisableAtimes(struct vnode *avp) { #ifdef AFS_DARWIN80_ENV struct vnode_attr vap; - vfs_context_t ctx; VATTR_INIT(&vap); VATTR_CLEAR_SUPPORTED(&vap, va_access_time); - ctx=vfs_context_create(NULL); - vnode_setattr2(avp, &vap, ctx); - vfs_context_rele(ctx); + vnode_setattr(avp, &vap, afs_osi_ctxtp); #else if (afs_CacheFSType == AFS_APPL_UFS_CACHE) { struct inode *ip = VTOI(avp); @@ -267,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); /** @@ -283,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; @@ -307,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"); @@ -314,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 c5e787dd6d..cf1ff43cf2 100644 --- a/src/afs/DARWIN/osi_groups.c +++ b/src/afs/DARWIN/osi_groups.c @@ -17,11 +17,20 @@ #include #include "afs/param.h" -/* We should be doing something better anyway */ -#ifndef AFS_DARWIN80_ENV 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 */ @@ -77,14 +86,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; diff --git a/src/afs/DARWIN/osi_inode.c b/src/afs/DARWIN/osi_inode.c index 3f5b7f4edd..3439a7e58b 100644 --- a/src/afs/DARWIN/osi_inode.c +++ b/src/afs/DARWIN/osi_inode.c @@ -36,58 +36,23 @@ getinode(fs, dev, inode, vpp, perror) ino_t inode; int *perror; { -#if 0 struct vnode *vp; int code; vfs_context_t ctx; + char volfspath[64]; *vpp = 0; *perror = 0; - if (!fs) { - register struct ufsmount *ump; -#ifdef VFSTOHFS - register struct hfsmount *hmp; -#endif - register vnode_t vp; - register mount_t mp; - mount_t rootfs = vfs_getvfs_by_mntonname("/"); - if (mp = rootfs) - do { - /* - * XXX Also do the test for MFS - */ - if (!strcmp(mp->mnt_vfc->vfc_name, "ufs")) { - ump = VFSTOUFS(mp); - if (ump->um_fs == NULL) - break; - if (ump->um_dev == dev) { - fs = ump->um_mountp; - } - } -#ifdef VFSTOHFS - if (!strcmp(mp->mnt_vfc->vfc_name, "hfs")) { - hmp = VFSTOHFS(mp); #if 0 - if (hmp->hfs_mp == NULL) - break; -#endif - if (hmp->hfs_raw_dev == dev) { - fs = hmp->hfs_mp; - } - } -#endif - - mp = CIRCLEQ_NEXT(mp, mnt_list); - } while (mp != rootfs); + if (!fs) { + fs = vfs_getvfs(&dev); if (!fs) return (ENXIO); } -#ifdef AFS_DARWIN80_ENV - ctx=vfs_context_create(NULL); - code = VFS_VGET(fs, (void *)inode, &vp, ctx); - vfs_context_rele(ctx); + code = VFS_VGET(fs, inode, &vp, afs_osi_ctxtp); #else - code = VFS_VGET(fs, (void *)inode, &vp); + sprintf(volfspath, "/.vol/%d/%d", dev, inode); + code = vnode_open(volfspath, O_RDWR, 0, 0, &vp, afs_osi_ctxtp); #endif if (code) { *perror = BAD_IGET; @@ -96,7 +61,6 @@ getinode(fs, dev, inode, vpp, perror) *vpp = vp; return (0); } -#endif } igetinode(vfsp, dev, inode, vpp, va, perror) @@ -118,25 +82,33 @@ igetinode(vfsp, dev, inode, vpp, va, perror) return (code); } if (vnode_vtype(vp) != VREG && vnode_vtype(vp) != VDIR && vnode_vtype(vp) != VLNK) { - vput(vp); + vnode_close(vp, O_RDWR, afs_osi_ctxtp); printf("igetinode: bad type %d\n", vnode_vtype(vp)); return (ENOENT); } - VOP_GETATTR(vp, va, &afs_osi_cred, current_proc()); + 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) { - vput(vp); + vnode_close(vp, O_RDWR, afs_osi_ctxtp); /* Not an allocated inode */ return (ENOENT); } - if (vfsp && afs_CacheFSType == AFS_APPL_HFS_CACHE && va->va_nlink == 0) { - printf("igetinode: hfs nlink 0\n"); - } if (va->va_nlink == 0) { - vput(vp); + vnode_close(vp, O_RDWR, afs_osi_ctxtp); return (ENOENT); } - VOP_UNLOCK(vp, 0, current_proc()); *vpp = vp; return (0); } diff --git a/src/afs/DARWIN/osi_machdep.h b/src/afs/DARWIN/osi_machdep.h index a34e32a209..80acb080e3 100644 --- a/src/afs/DARWIN/osi_machdep.h +++ b/src/afs/DARWIN/osi_machdep.h @@ -37,13 +37,21 @@ typedef unsigned short etap_event_t; #include #ifdef AFS_DARWIN80_ENV -#define ctx_proc vfs_context_proc(ap->a_context) -#define ctx_cred vfs_context_ucred(ap->a_context) +#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 ctx_proc cnp->cn_proc; -#define ctx_cred cnp->cn_cred; +#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 @@ -60,13 +68,25 @@ enum vcexcl { EXCL, NONEXCL }; #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_put +#define vput(v) do { vnode_put((v)); vnode_rele((v)); } while(0) #define vref vnode_ref #define vattr vnode_attr +#define VOP_LOCK(v, unused1, unused2) vnode_get((v)) +#define VOP_UNLOCK(v, unused1, unused2) vnode_put((v)) #define va_size va_data_size #define va_atime va_access_time @@ -76,21 +96,13 @@ enum vcexcl { EXCL, NONEXCL }; #define va_blocksize va_iosize #define va_nodeid va_fileid -//afs_osi_ctxp +#define crref kauth_cred_get_with_ref +#define crhold kauth_cred_ref +#define crfree kauth_cred_rele +#define crdup kauth_cred_dup -#define SetAfsVnode(vn) /* nothing; done in getnewvnode() */ -/* vnode_vfsfsprivate is not declared, so no macro for us */ -extern void * afs_fsprivate_data; -static inline int IsAfsVnode(vnode_t vn) { - mount_t mp; - int res = 0; - mp = vnode_mount(vn); - if (mp) { - res = (vfs_fsprivate(mp) == &afs_fsprivate_data); - vfs_mountrelease(mp); - } - return res; -} +extern vfs_context_t afs_osi_ctxtp; +extern int afs_osi_ctxtp_initialized; #endif /* @@ -123,6 +135,10 @@ extern int hz; #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()) @@ -137,7 +153,7 @@ extern thread_t afs_global_owner; extern lck_mtx_t *afs_global_lock; #define AFS_GLOCK() \ do { \ - lk_mtx_lock(afs_global_lock); \ + lck_mtx_lock(afs_global_lock); \ osi_Assert(afs_global_owner == 0); \ afs_global_owner = current_thread(); \ } while (0) @@ -145,7 +161,7 @@ extern lck_mtx_t *afs_global_lock; do { \ osi_Assert(afs_global_owner == current_thread()); \ afs_global_owner = 0; \ - lk_mtx_unlock(afs_global_lock); \ + lck_mtx_unlock(afs_global_lock); \ } while(0) #else /* Should probably use mach locks rather than bsd locks, since we use the @@ -185,6 +201,8 @@ extern struct lock__bsd__ afs_global_lock; 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() @@ -193,6 +211,8 @@ extern dev_t VnodeToDev(struct vnode * vp); #ifdef AFS_DARWIN80_ENV uio_t afsio_darwin_partialcopy(uio_t auio, int size); + +#define uprintf printf #endif #endif /* KERNEL */ diff --git a/src/afs/DARWIN/osi_misc.c b/src/afs/DARWIN/osi_misc.c index c77c6a62d8..9263b13eaf 100644 --- a/src/afs/DARWIN/osi_misc.c +++ b/src/afs/DARWIN/osi_misc.c @@ -41,6 +41,10 @@ osi_lookupname(char *aname, enum uio_seg seg, int 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; } @@ -79,7 +83,10 @@ afs_suser(void *credp) struct proc *p = current_proc(); #ifdef AFS_DARWIN80_ENV - return proc_suser(p); + if ((error = proc_suser(p)) == 0) { + return (1); + } + return (0); #else if ((error = suser(p->p_ucred, &p->p_acflag)) == 0) { return (1); @@ -111,4 +118,106 @@ uio_t afsio_darwin_partialcopy(uio_t auio, int size) { } 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; +} +int +afs_cdev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) { + int retval=0; + struct afssysargs *a = data; + if (proc_is64bit(p)) + return EINVAL; + + if (cmd != VIOC_SYSCALL) { + printf("ioctl mismatch 0x%lx (wanted 0x%lx)\n", cmd, VIOC_SYSCALL); + /*return EINVAL;*/ + } + + afs3_syscall(p, (struct afssysargs *)data, &retval); + return retval; +} + #endif diff --git a/src/afs/DARWIN/osi_module.c b/src/afs/DARWIN/osi_module.c index 827a7bd7cb..5c1720a614 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,9 +81,11 @@ afs_modload(struct kmod_info *ki, void *data) printf("AFS: vfsconf_add failed. aborting\n"); return KERN_FAILURE; } -#ifndef AFS_DARWIN80_ENV + if (sysent[AFS_SYSCALL].sy_call != nosys) { + printf("AFS_SYSCALL in use. aborting\n"); + return KERN_FAILURE; + } sysent[SYS_setgroups].sy_call = Afs_xsetgroups; -#endif #if 0 sysent[SYS_ioctl].sy_call = afs_xioctl; #endif @@ -51,9 +95,10 @@ afs_modload(struct kmod_info *ki, void *data) #ifdef KERNEL_FUNNEL sysent[AFS_SYSCALL].sy_funnel = KERNEL_FUNNEL; #endif +#endif #ifdef AFS_DARWIN80_ENV MUTEX_SETUP(); - afs_global_lock = lck_mtx_alloc(openafs_lck_grp, 0); + afs_global_lock = lck_mtx_alloc_init(openafs_lck_grp, 0); #endif return KERN_SUCCESS; } @@ -63,6 +108,12 @@ 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 */ @@ -75,12 +126,13 @@ afs_modunload(struct kmod_info * ki, void *data) /* 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); + 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 c97588bba3..8dac77d1d6 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 void afs_darwin_getnewvnode(struct vcache *avc); +extern void 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 8a85984c52..582215a7f5 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,9 +157,9 @@ afs_osi_Sleep(void *event) void afs_osi_fullSigMask() { +#ifndef AFS_DARWIN80_ENV struct uthread *user_thread = (struct uthread *)get_bsdthread_info(current_act()); -#ifndef AFS_DARWIN80_ENV /* Protect original sigmask */ if (!user_thread->uu_oldmask) { /* Back up current sigmask */ @@ -169,9 +173,9 @@ afs_osi_fullSigMask() void afs_osi_fullSigRestore() { +#ifndef AFS_DARWIN80_ENV struct uthread *user_thread = (struct uthread *)get_bsdthread_info(current_act()); -#ifndef AFS_DARWIN80_ENV /* Protect original sigmask */ if (user_thread->uu_oldmask) { /* Restore original sigmask */ @@ -205,6 +209,9 @@ osi_TimedSleep(char *event, afs_int32 ams, int aintok) struct afs_event *evp; int ticks, seq; int prio; +#ifdef AFS_DARWIN80_ENV + struct timespec ts; +#endif ticks = (ams * afs_hz) / 1000; @@ -212,6 +219,15 @@ osi_TimedSleep(char *event, afs_int32 ams, int aintok) 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 #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 @@ -231,6 +247,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 74b9bd4ce6..a31e9bd55c 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,29 +175,33 @@ 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); +#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) { @@ -174,7 +224,7 @@ afs_unmount(mp, flags, p) return EBUSY; } } - mp->mnt_flag &= ~MNT_LOCAL; + vfs_clearflags(mp, MNT_LOCAL); } AFS_GUNLOCK(); @@ -182,40 +232,51 @@ 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); +#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) { + } else if (mdata == (qaddr_t) - 1) { error = ENOENT; } else { - struct VenusFid *rootFid = (mp->mnt_data == NULL) - ? &afs_rootFid : (struct VenusFid *)mp->mnt_data; + struct VenusFid *rootFid = (mdata == NULL) + ? &afs_rootFid : (struct VenusFid *)mdata; if (afs_globalVp) { afs_PutVCache(afs_globalVp); afs_globalVp = NULL; } - 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); /* we really want this to stay around */ if (tvp) { - if (mp->mnt_data == NULL) + if (mdata == NULL) afs_globalVp = tvp; } else error = ENOENT; @@ -224,14 +285,20 @@ afs_root(struct mount *mp, struct vnode **vpp) if (tvp) { osi_vnhold(tvp, 0); AFS_GUNLOCK(); +#ifdef AFS_DARWIN80_ENV + afs_darwin_finalizevnode(tvp, NULL, NULL, 1); +#else vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, p); +#endif AFS_GLOCK(); - if (mp->mnt_data == NULL) { + if (mdata == NULL) { afs_globalVFS = mp; } *vpp = AFSTOV(tvp); +#ifndef AFS_DARWIN80_ENV /* XXX VROOT can only be set in vnode_create */ AFSTOV(tvp)->v_flag |= VROOT; AFSTOV(tvp)->v_vfsp = mp; +#endif } afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *vpp, @@ -240,6 +307,7 @@ afs_root(struct mount *mp, struct vnode **vpp) return error; } +#if 0 /* vget never had this prototype AFAIK */ int afs_vget(mp, lfl, vp) struct mount *mp; @@ -261,18 +329,36 @@ afs_vget(mp, lfl, vp) insmntque(vp, mp); /* take off free list */ return error; } +#else + +#ifdef AFS_DARWIN80_ENV +int afs_vget(struct mount *mp, ino64_t ino, struct vnode **vpp, + vfs_context_t ctx) +#else +int afs_vget(struct mount *mp, void *ino, struct vnode **vpp) +#endif +{ + 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 @@ -281,34 +367,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; @@ -323,8 +486,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 */ @@ -340,6 +508,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; @@ -401,19 +570,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_vget, + afs_fhtovp, + afs_vptofh, +#endif + afs_init, + afs_sysctl, +#ifdef AFS_DARWIN80_ENVX + 0 /*setattr */, + {0} +#endif }; diff --git a/src/afs/DARWIN/osi_vm.c b/src/afs/DARWIN/osi_vm.c index 1285bf2f47..89fb2f614b 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,12 @@ osi_VM_FlushPages(struct vcache *avc, struct AFS_UCRED *credp) void *object; kern_return_t kret; off_t size; +#ifdef AFS_DARWIN80_ENV + ubc_sync_range(vp, 0, ubc_getsize(vp), 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 +140,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 +153,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 +186,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 +206,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 d0dfb7b007..02f1c8b1eb 100644 --- a/src/afs/DARWIN/osi_vnodeops.c +++ b/src/afs/DARWIN/osi_vnodeops.c @@ -18,16 +18,34 @@ RCSID #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 +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) *); @@ -149,8 +167,8 @@ struct vnodeopv_entry_desc afs_vnodeop_entries[] = { {VOPPREF(vfree_desc), (VOPFUNC)afs_vop_vfree}, /* vfree */ {VOPPREF(update_desc), (VOPFUNC)afs_vop_update}, /* update */ {VOPPREF(cmap_desc), (VOPFUNC)afs_vop_cmap}, /* cmap */ -#endif {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}, @@ -159,6 +177,50 @@ struct vnodeopv_entry_desc afs_vnodeop_entries[] = { 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; \ @@ -174,35 +236,38 @@ darwin_vn_hold(struct vnode *vp) int haveGlock=ISAFS_GLOCK(); struct vcache *tvc = VTOAFS(vp); +#ifndef AFS_DARWIN80_ENV tvc->states |= CUBCinit; +#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_GT(tvc, 0)) -#ifdef AFS_DARWIN80_ENV - vnode_ref(vp); -#else VREF(((struct vnode *)(vp))); -#endif - else -#ifdef AFS_DARWIN80_ENV - vnode_get(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 VOPPROT(lookup_args)/* { @@ -220,12 +285,12 @@ afs_vop_lookup(ap) int wantparent; /* 1 => wantparent or lockparent flag */ struct proc *p; GETNAME(); - p = ctx_proc; + p = vop_cn_proc; lockparent = flags & LOCKPARENT; wantparent = flags & (LOCKPARENT | WANTPARENT); - if (vnode_type(ap->a_dvp) != VDIR) { + if (vnode_isdir(ap->a_dvp)) { *ap->a_vpp = 0; DROPNAME(); return ENOTDIR; @@ -234,13 +299,11 @@ afs_vop_lookup(ap) if (flags & ISDOTDOT) VOP_UNLOCK(dvp, 0, p); AFS_GLOCK(); - error = afs_lookup(VTOAFS(dvp), name, &vcp, ctx_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; @@ -252,19 +315,24 @@ afs_vop_lookup(ap) *ap->a_vpp = 0; return (error); } +#ifdef AFS_DARWIN80_ENV + afs_darwin_finalizevnode(vcp, ap->a_dvp, ap->a_cnp, 0); +#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. */ -#ifndef AFS_DARWIN80_ENV if (flags & ISDOTDOT) { vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); /* always return the child locked */ @@ -283,7 +351,6 @@ 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 @@ -295,6 +362,7 @@ afs_vop_lookup(ap) DROPNAME(); return error; } +#endif int afs_vop_create(ap) @@ -310,13 +378,13 @@ 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) { VOP_ABORTOP(dvp, cnp); @@ -326,7 +394,11 @@ afs_vop_create(ap) } 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); if (UBCINFOMISSING(*ap->a_vpp) || UBCINFORECLAIMED(*ap->a_vpp)) { @@ -334,6 +406,7 @@ afs_vop_create(ap) ubc_info_init(*ap->a_vpp); vcp->states &= ~CUBCinit; } +#endif } else *ap->a_vpp = 0; @@ -374,7 +447,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 @@ -390,14 +463,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 */ @@ -417,16 +490,102 @@ 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 +int +afs_vop_access(ap) + 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 fail2; + + code = afs_EvalFakeStat(&tvc, &fakestate, &treq); + if (code) { + code = afs_CheckCode(code, &treq, 55); + goto fail; + } + + code = afs_VerifyVCache(tvc, &treq); + if (code) { + code = afs_CheckCode(code, &treq, 56); + goto fail; + } + 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 + 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 */ + } +fail: + afs_PutFakeStat(&fakestate); +fail2: + AFS_GUNLOCK(); + return code; +} +#else int afs_vop_access(ap) struct VOPPROT(access_args) /* { @@ -438,10 +597,11 @@ 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) @@ -455,8 +615,24 @@ 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; } @@ -471,7 +647,7 @@ 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; } @@ -488,9 +664,16 @@ 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; } @@ -515,14 +698,19 @@ 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"); @@ -531,41 +719,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); @@ -575,21 +769,32 @@ 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 + do { + int len = AFS_UIO_RESID(uio); + if (len > AFS_ZEROS) + len = AFS_ZEROS; + code = uiomove(afs_zeros, len, uio); + } while (code == 0 && AFS_UIO_RESID(uio) > 0); +#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; } @@ -605,16 +810,20 @@ 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; } @@ -639,15 +848,20 @@ 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"); @@ -656,10 +870,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; @@ -684,11 +902,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); } @@ -696,13 +914,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); } @@ -719,20 +937,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 [ */ { /* @@ -749,7 +972,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); @@ -760,19 +983,20 @@ 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; } @@ -858,14 +1082,15 @@ 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 VOPPROT(seek_args) /* { @@ -879,6 +1104,7 @@ afs_vop_seek(ap) return EINVAL; return (0); } +#endif int afs_vop_remove(ap) @@ -894,16 +1120,20 @@ afs_vop_remove(ap) 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); +#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 } if (dvp == vp) @@ -932,24 +1162,28 @@ 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: vput(dvp); DROPNAME(); @@ -976,8 +1210,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 */ @@ -986,6 +1227,7 @@ afs_vop_rename(ap) error = EXDEV; goto abortit; } +#endif /* * if fvp == tvp, we're just removing one name of a pair of @@ -993,7 +1235,7 @@ afs_vop_rename(ap) ( (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? */ @@ -1013,8 +1255,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; @@ -1030,8 +1282,9 @@ afs_vop_rename(ap) if (fvp == NULL) { return (ENOENT); } - error=VOP_REMOVE(fdvp, fvp, fcnp); +#endif + if (fdvp == fvp) vrele(fdvp); else @@ -1039,8 +1292,10 @@ afs_vop_rename(ap) vput(fvp); return (error); } +#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); @@ -1053,10 +1308,12 @@ 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); if (error) @@ -1088,13 +1345,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); @@ -1103,9 +1360,14 @@ 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(); @@ -1140,7 +1402,7 @@ afs_vop_rmdir(ap) } AFS_GLOCK(); - error = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred); + error = afs_rmdir(VTOAFS(dvp), name, vop_cn_cred); AFS_GUNLOCK(); DROPNAME(); vput(dvp); @@ -1165,7 +1427,7 @@ 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 @@ -1190,11 +1452,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; @@ -1221,6 +1490,7 @@ afs_vop_readdir(ap) *ap->a_cookies = cookies; *ap->a_ncookies = ncookies; } +#endif return error; } @@ -1236,7 +1506,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; } @@ -1252,8 +1522,10 @@ afs_vop_inactive(ap) { register struct vnode *vp = ap->a_vp; - if (prtactive && vp->v_usecount != 0) +#ifndef AFS_DARWIN80_ENV + if (prtactive && vnode_isinuse(vp, 0) != 0) vprint("afs_vop_inactive(): pushing active", vp); +#endif AFS_GLOCK(); afs_InactiveVCache(VTOAFS(vp), 0); /* decrs ref counts */ @@ -1279,11 +1551,13 @@ afs_vop_reclaim(ap) cache_purge(vp); /* just in case... */ if (!haveGlock) AFS_GLOCK(); + ObtainWriteLock(&afs_xvcache, 335); error = afs_FlushVCache(VTOAFS(vp), &sl); /* toss our stuff from vnode */ + ReleaseWriteLock(&afs_xvcache); if (!haveGlock) AFS_GUNLOCK(); - if (!error && vp->v_data) + if (!error && vnode_fsnode(vp)) panic("afs_reclaim: vnode not cleaned"); if (!error && (tvc->v != NULL)) panic("afs_reclaim: vcache not cleaned"); @@ -1356,14 +1630,20 @@ afs_vop_advlock(ap) * } */ *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, &cr, (int)ap->a_id); + afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, tcr, (int)ap->a_id); AFS_GUNLOCK(); return error; } @@ -1559,9 +1839,20 @@ afs_darwin_getnewvnode(struct vcache *tvc) #ifdef AFS_DARWIN80_ENV vnode_t vp; int error; + struct vnode_fsparam par; - error = vnode_create(VNCREATE_FLAVOR, VCREATESIZE, afs_globalVFS, &vp); - vnode_settag(vp, VT_AFS); + memset(&par, 0, sizeof(struct vnode_fsparam)); + par.vnfs_mp = afs_globalVFS; + par.vnfs_vtype = VNON; + par.vnfs_vops = afs_dead_vnodeop_p; + par.vnfs_fsnode = tvc; + par.vnfs_flags = VNFS_NOCACHE|VNFS_CANTCACHE; + error = vnode_create(VNCREATE_FLAVOR, VCREATESIZE, &par, &vp); + if (!error) { + tvc->v = vp; + vnode_recycle(vp); /* terminate as soon as iocount drops */ + tvc->states |= CDeadVnode; + } #else while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &tvc->v)) { /* no vnodes available, force an alloc (limits be damned)! */ @@ -1570,3 +1861,41 @@ afs_darwin_getnewvnode(struct vcache *tvc) tvc->v->v_data = (void *)tvc; #endif } +#ifdef AFS_DARWIN80_ENV +void +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(); + return; + } + 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_fsnode = avc; + par.vnfs_dvp = dvp; + par.vnfs_cnp = cnp; + par.vnfs_filesize = avc->m.Length; + if (isroot) + par.vnfs_markroot = 1; + error = vnode_create(VNCREATE_FLAVOR, VCREATESIZE, &par, &nvp); + if (!error) { + avc->v = nvp; + avc->states &=~ CDeadVnode; + vnode_clearfsnode(ovp); + vnode_put(ovp); + } + AFS_GLOCK(); + ReleaseWriteLock(&avc->lock); + afs_osi_Wakeup(&avc->v); + AFS_GUNLOCK(); +} +#endif diff --git a/src/afs/VNOPS/afs_vnop_attrs.c b/src/afs/VNOPS/afs_vnop_attrs.c index 8296aa7bd9..d393454de3 100644 --- a/src/afs/VNOPS/afs_vnop_attrs.c +++ b/src/afs/VNOPS/afs_vnop_attrs.c @@ -224,7 +224,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; @@ -343,7 +343,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) @@ -363,7 +365,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) { @@ -381,7 +385,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) { @@ -399,7 +405,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) { @@ -476,7 +484,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) { @@ -507,7 +517,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 4232f4512a..eb0073aa6e 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_read.c b/src/afs/VNOPS/afs_vnop_read.c index c637f572ad..822fd77f04 100644 --- a/src/afs/VNOPS/afs_vnop_read.c +++ b/src/afs/VNOPS/afs_vnop_read.c @@ -833,13 +833,7 @@ afs_UFSRead(register struct vcache *avc, struct uio *auio, AFS_GLOCK(); #elif defined(AFS_DARWIN80_ENV) AFS_GUNLOCK(); - code = VOP_READ(tfile->vnode, tuiop, 0, afs_osi_credp); - AFS_GLOCK(); -#elif defined(AFS_DARWIN_ENV) - AFS_GUNLOCK(); - VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, current_proc()); - code = VOP_READ(tfile->vnode, &tuio, 0, afs_osi_credp); - VOP_UNLOCK(tfile->vnode, 0, current_proc()); + code = VNOP_READ(tfile->vnode, tuiop, 0, afs_osi_ctxtp); AFS_GLOCK(); #elif defined(AFS_DARWIN_ENV) AFS_GUNLOCK(); diff --git a/src/afs/VNOPS/afs_vnop_remove.c b/src/afs/VNOPS/afs_vnop_remove.c index a00b80eb26..bf7ca3fcfb 100644 --- a/src/afs/VNOPS/afs_vnop_remove.c +++ b/src/afs/VNOPS/afs_vnop_remove.c @@ -443,7 +443,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_write.c b/src/afs/VNOPS/afs_vnop_write.c index 91beb171af..9b46da8163 100644 --- a/src/afs/VNOPS/afs_vnop_write.c +++ b/src/afs/VNOPS/afs_vnop_write.c @@ -597,7 +597,7 @@ afs_UFSWrite(register struct vcache *avc, struct uio *auio, int aio, AFS_GLOCK(); #elif defined(AFS_DARWIN80_ENV) AFS_GUNLOCK(); - code = VOP_WRITE(tfile->vnode, tuiop, 0, afs_osi_credp); + code = VNOP_WRITE(tfile->vnode, tuiop, 0, afs_osi_ctxtp); AFS_GLOCK(); #elif defined(AFS_DARWIN_ENV) AFS_GUNLOCK(); diff --git a/src/afs/afs.h b/src/afs/afs.h index 10ddf6003b..305a17323a 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -526,12 +526,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 @@ -639,7 +643,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) diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index db2f9e1f55..872ccca3fd 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; @@ -1370,7 +1392,9 @@ Afs_syscall() uap->parm6 = 0; } #endif - +#if defined(AFS_DARWIN80_ENV) + get_vfs_context(); +#endif #if defined(AFS_HPUX_ENV) /* * There used to be code here (duplicated from osi_Init()) for @@ -1417,6 +1441,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 +1533,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_daemons.c b/src/afs/afs_daemons.c index 7ee41b7ac2..214c9192bb 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; diff --git a/src/afs/afs_init.c b/src/afs/afs_init.c index a429ed3e92..b2503aefd1 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 */ @@ -383,7 +385,7 @@ afs_InitCacheInfo(register char *afile) } #elif defined(AFS_DARWIN80_ENV) afs_cacheVfsp = vnode_mount(filevp); - if (afs_cacheVfsp && !VFS_STATFS(afs_cacheVfsp, &st, current_proc())) + 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) diff --git a/src/afs/afs_osi.c b/src/afs/afs_osi.c index 7b6d2600c2..eeebdf29b4 100644 --- a/src/afs/afs_osi.c +++ b/src/afs/afs_osi.c @@ -76,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()); @@ -84,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; @@ -336,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 @@ -563,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"); } diff --git a/src/afs/afs_osi.h b/src/afs/afs_osi.h index 814b3af8e0..f3b6e3f3d2 100644 --- a/src/afs/afs_osi.h +++ b/src/afs/afs_osi.h @@ -125,6 +125,11 @@ struct afs_osi_WaitHandle { */ #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) #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) #define vSetVfsp(vc, vfsp) AFSTOV(vc)->v_mount = (vfsp) #define vSetType(vc, type) AFSTOV(vc)->v_type = (type) @@ -270,6 +275,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) \ @@ -277,7 +287,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) @@ -287,7 +297,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) @@ -297,7 +307,7 @@ 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) @@ -342,17 +352,17 @@ typedef struct timeval osi_timeval_t; #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) diff --git a/src/afs/afs_osi_pag.c b/src/afs/afs_osi_pag.c index 8c64aec4b6..8d49baf538 100644 --- a/src/afs/afs_osi_pag.c +++ b/src/afs/afs_osi_pag.c @@ -243,7 +243,7 @@ afs_setpag(void) } #elif defined(AFS_DARWIN80_ENV) { - struct ucred *credp = kauth_cred_dup(proc_ucred(p)); + struct ucred *credp = kauth_cred_proc_ref(p); code = AddPag(p, genpag(), &credp); kauth_cred_rele(credp); } diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index 18e02d53a1..a08f886e3f 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 diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 0d19994511..ee95ceb1d2 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -732,7 +732,11 @@ restart: * XXX assume FreeBSD is the same for now. */ AFS_GUNLOCK(); +#ifdef AFS_DARWIN80_ENV + vnode_recycle(AFSTOV(tvc)); +#else vgone(AFSTOV(tvc)); +#endif AFS_GLOCK(); code = fv_slept = 0; #else @@ -859,7 +863,11 @@ restart: tvc->execsOrWriters = 0; tvc->flockCount = 0; tvc->anyAccess = 0; +#ifdef AFS_DARWIN80_ENV + tvc->states = CDeadVnode; +#else tvc->states = 0; +#endif tvc->last_looker = 0; tvc->fid = *afid; tvc->asynchrony = -1; @@ -1719,6 +1727,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. @@ -1738,7 +1750,7 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq, #if defined(AFS_DARWIN_ENV) iheldthelock = VOP_ISLOCKED(vp); if (!iheldthelock) - vnode_lock(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, current_proc()); /* this is messy. we can call fsync which will try to reobtain this */ if (VTOAFS(vp) == tvc) ReleaseWriteLock(&tvc->lock); @@ -1748,11 +1760,7 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq, if (VTOAFS(vp) == tvc) ObtainWriteLock(&tvc->lock, 954); if (!iheldthelock) -#ifdef AFS_DARWIN80_ENV - vnode_unlock(vp); -#else VOP_UNLOCK(vp, LK_EXCLUSIVE, current_proc()); -#endif #elif defined(AFS_FBSD60_ENV) iheldthelock = VOP_ISLOCKED(vp, curthread); if (!iheldthelock) @@ -1783,6 +1791,7 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq, VOP_UNLOCK(vp, 0, curproc); #endif } +#endif #endif ObtainWriteLock(&afs_xcbhash, 464); @@ -2499,7 +2508,9 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag) afs_int32 i; AFS_STATCNT(afs_FindVCache); - +#ifdef AFS_DARWIN80_ENV +findloop: +#endif i = VCHash(afid); for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) { if (FidMatches(afid, tvc)) { @@ -2512,6 +2523,31 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag) if (vg) continue; #endif /* AFS_OSF_ENV */ +#ifdef AFS_DARWIN80_ENV + int vg; + /* wait for the vnode to be replaced by afs_darwin_finalizevnode + or reclaimed. locks must be released so reclaim doesn't block */ + if (tvc->flags & CDeadVnode) { + int lock; + lock = CheckLock(&afs_vcache); + if (lock > 0) + ReleaseReadLock(&afs_vcache); + else + ReleaseSharedLock(&afs_vcache); + osi_TimedSleep(&tvc->v, 500, 0); + if (lock > 0) + ObtainReadLock(&afs_vcache); + else + ObtainSharedLock(&afs_vcache, 344); + goto findloop; + } + AFS_GUNLOCK(); + vg = vnode_get(AFSTOV(tvc)); + AFS_GLOCK(); + if (vg) + continue; + +#endif break; } } @@ -2520,12 +2556,12 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag) if (tvc) { if (retry) *retry = 0; -#if !defined(AFS_OSF_ENV) +#if !defined(AFS_OSF_ENV) && !defined(AFS_DARWIN80_ENV) osi_vnhold(tvc, retry); /* already held, above */ 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)) || diff --git a/src/afs/sysincludes.h b/src/afs/sysincludes.h index ade3cdc77c..33993e8e5e 100644 --- a/src/afs/sysincludes.h +++ b/src/afs/sysincludes.h @@ -252,10 +252,10 @@ struct vop_getwritemount_args; # include # include #ifdef AFS_DARWIN80_ENV -# include -#else -# include +# include +#include #endif +# include # include # include #ifndef AFS_FBSD_ENV diff --git a/src/afsd/afsd.c b/src/afsd/afsd.c index 94b6cdf67c..bea683a55c 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 *); @@ -1806,8 +1809,10 @@ mainproc(as, 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. @@ -2329,9 +2334,27 @@ call_syscall(param1, param2, param3, param4, param5, param6, param7) } 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; + } +#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 7f969c38fe..d208ebef27 100644 --- a/src/config/afs_args.h +++ b/src/config/afs_args.h @@ -211,5 +211,19 @@ struct afsprocdata32 { #endif +#ifdef AFS_DARWIN80_ENV +struct afssysargs { + long syscall; + long param1; + long param2; + long param3; + long param4; + long param5; + long param6; +}; +#define VIOC_SYSCALL_TYPE 'C' +#define VIOC_SYSCALL _IOW(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 2ab604c32b..097f88d89d 100644 --- a/src/config/param.ppc_darwin_80.h +++ b/src/config/param.ppc_darwin_80.h @@ -57,8 +57,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 diff --git a/src/dir/dir.c b/src/dir/dir.c index 22bd3f31d4..4291fecdcf 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) +#if defined(AFS_SUN56_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_DARWIN80_ENV) #include "afs/sysincludes.h" #endif #if defined(AFS_FBSD_ENV) diff --git a/src/libafs/MakefileProto.DARWIN.in b/src/libafs/MakefileProto.DARWIN.in index 7bee813059..b528d47ce3 100644 --- a/src/libafs/MakefileProto.DARWIN.in +++ b/src/libafs/MakefileProto.DARWIN.in @@ -34,7 +34,10 @@ 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 -fsigned-bitfields -arch ppc -Dppc -DPPC -D__PPC__ -DPAGE_SIZE_FIXED -O2 -mcpu=750 -mmultiple -fschedule-insns +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 @@ -100,7 +103,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 0383e3e827..08938589b0 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/rx/DARWIN/rx_kmutex.h b/src/rx/DARWIN/rx_kmutex.h index 92275d03db..07fb0246f6 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(); \ @@ -84,6 +106,8 @@ #ifdef AFS_DARWIN80_ENV typedef struct { + lck_mtx_t *meta; + int waiters; /* also includes anyone holding the lock */ lck_mtx_t *lock; thread_t owner; } afs_kmutex_t; @@ -95,36 +119,62 @@ extern lck_grp_t * openafs_lck_grp; #define MUTEX_FINISH() rx_kmutex_finish() #define LOCKINIT(a) \ do { \ - lck_attr_t * openafs_lck_attr = lck_attr_alloc_init(); \ + 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); + } while(0) #define MUTEX_INIT(a,b,c,d) \ do { \ - lck_attr_t * openafs_lck_attr = lck_attr_alloc_init(); \ + 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); + } 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); + } while(0) #define MUTEX_ENTER(a) \ do { \ - lck_mtx_lock(&(a)->lock); \ + 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); -#define MUTEX_TRYENTER(a) \ - (lck_mtx_try_lock(&(a)->lock) ? ((a)->owner = current_thread(), 1) : 0) + } 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); \ - } while(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()) diff --git a/src/rx/DARWIN/rx_knet.c b/src/rx/DARWIN/rx_knet.c index 589396faae..9e02292796 100644 --- a/src/rx/DARWIN/rx_knet.c +++ b/src/rx/DARWIN/rx_knet.c @@ -15,22 +15,27 @@ 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; - uio_t up; + struct msghdr msg; + struct sockaddr_storage ss; #else struct socket *asocket = (struct socket *)so; struct uio u; - struct uio *up = &u; #endif int i; struct iovec iov[RX_MAXIOVECS]; struct sockaddr *sa = NULL; int code; + size_t rlen; int haveGlock = ISAFS_GLOCK(); /*AFS_STATCNT(osi_NetReceive); */ @@ -38,18 +43,22 @@ osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec, if (nvecs > RX_MAXIOVECS) osi_Panic("osi_NetReceive: %d: Too many iovecs.\n", nvecs); -#ifdef AFS_DARWIN80_ENV - up = uio_create(nvecs, 0, UIO_SYSSPACE, UIO_READ); - for (i = 0; i < nvecs; i++) { - /* is (user_addr_t) needed? */ - code = uio_addiov(up, (user_addr_t) dvec[i].iov_base, dvec[i].iov_len); - if (code) - return code; - } - -#else 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 + memset(&msg, 0, sizeof(struct msghdr)); + msg.msg_name = &ss; + msg.msg_namelen = sizeof(struct sockaddr_storage); + msg.msg_iov = &iov[0]; + msg.msg_iovlen = nvecs; + sa =(struct sockaddr_in *) &ss; + code = sock_receive(asocket, &msg, 0, &rlen); +#else u.uio_iov = &iov[0]; u.uio_iovcnt = nvecs; @@ -58,14 +67,10 @@ 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; + code = soreceive(asocket, &sa, &u, NULL, NULL, NULL); + rlen = u.uio_resid; #endif - if (haveGlock) - AFS_GUNLOCK(); -#if defined(KERNEL_FUNNEL) - thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); -#endif - code = soreceive(asocket, &sa, up, NULL, NULL, NULL); #if defined(KERNEL_FUNNEL) thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); #endif @@ -74,7 +79,7 @@ osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec, if (code) return code; - *alength -= AFS_UIO_RESID(up); + *alength -= rlen; if (sa) { if (sa->sa_family == AF_INET) { if (addr) @@ -99,9 +104,13 @@ osi_StopListener(void) #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 @@ -110,11 +119,11 @@ osi_NetSend(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec, { #ifdef AFS_DARWIN80_ENV socket_t asocket = (socket_t)so; - uio_t up; + struct msghdr msg; + size_t slen; #else struct socket *asocket = (struct socket *)so; struct uio u; - struct uio *up = &u; #endif register afs_int32 code; int i; @@ -125,27 +134,9 @@ osi_NetSend(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec, if (nvecs > RX_MAXIOVECS) osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs); -#ifdef AFS_DARWIN80_ENV - up = uio_create(nvecs, 0, UIO_SYSSPACE, UIO_WRITE); - for (i = 0; i < nvecs; i++) { - /* is (user_addr_t) needed? */ - code = uio_addiov(up, (user_addr_t) dvec[i].iov_base, dvec[i].iov_len); - if (code) - return code; - } -#else for (i = 0; i < nvecs; i++) iov[i] = dvec[i]; - u.uio_iov = &iov[0]; - u.uio_iovcnt = nvecs; - u.uio_offset = 0; - u.uio_resid = alength; - u.uio_segflg = UIO_SYSSPACE; - u.uio_rw = UIO_WRITE; - u.uio_procp = NULL; -#endif - addr->sin_len = sizeof(struct sockaddr_in); if (haveGlock) @@ -153,7 +144,24 @@ osi_NetSend(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec, #if defined(KERNEL_FUNNEL) thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); #endif - code = sosend(asocket, (struct sockaddr *)addr, up, NULL, NULL, 0); +#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; + u.uio_resid = alength; + u.uio_segflg = UIO_SYSSPACE; + u.uio_rw = UIO_WRITE; + u.uio_procp = NULL; + code = sosend(asocket, (struct sockaddr *)addr, &u, NULL, NULL, 0); +#endif + #if defined(KERNEL_FUNNEL) thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); #endif diff --git a/src/rx/UKERNEL/rx_kcommon.h b/src/rx/UKERNEL/rx_kcommon.h index 765d7cea22..a30260f331 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 f816517691..8793c9a62d 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) @@ -827,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 @@ -876,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 */ @@ -911,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); @@ -1203,7 +1232,7 @@ rxk_Listener(void) #if defined(RX_ENABLE_LOCKS) && !defined(AFS_SUN5_ENV) AFS_GUNLOCK(); #endif /* RX_ENABLE_LOCKS && !AFS_SUN5_ENV */ - +printf("rxk_Listener starting...\n"); while (afs_termState != AFSOP_STOP_RXK_LISTENER) { if (rxp) { rxi_RestoreDataBufs(rxp); @@ -1213,6 +1242,7 @@ rxk_Listener(void) osi_Panic("rxk_Listener: No more Rx buffers!\n"); } if (!(code = rxk_ReadPacket(rx_socket, rxp, &host, &port))) { + printf("."); rxp = rxi_ReceivePacket(rxp, rx_socket, host, port, 0, 0); } } diff --git a/src/rx/rx_kcommon.h b/src/rx/rx_kcommon.h index fc63e244f6..1e19c282ab 100644 --- a/src/rx/rx_kcommon.h +++ b/src/rx/rx_kcommon.h @@ -163,7 +163,7 @@ extern struct domain inetdomain; #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 ifnet_mtu(x) (x)->if_mtu*/ #define ifaddr_withnet(x) ifa_ifwithnet(x) #endif diff --git a/src/rx/rx_kernel.h b/src/rx/rx_kernel.h index da3555c4a5..d147e3b0ad 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 7438657151..fd9f380243 100644 --- a/src/rx/rx_packet.c +++ b/src/rx/rx_packet.c @@ -1588,7 +1588,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 1d06d5335f..b8147494c8 100644 --- a/src/rx/rx_prototypes.h +++ b/src/rx/rx_prototypes.h @@ -348,12 +348,12 @@ 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 -#endif extern void osi_StopListener(void); diff --git a/src/rx/xdr.c b/src/rx/xdr.c index 469352a511..5816ef162c 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/sys/afssyscalls.c b/src/sys/afssyscalls.c index 7bb25a9ed2..1c3d9e6d4a 100644 --- a/src/sys/afssyscalls.c +++ b/src/sys/afssyscalls.c @@ -314,7 +314,30 @@ 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 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.param4 = param5; + syscall_data.param4 = param6; + + *rval = ioctl(fd, VIOC_SYSCALL, &syscall_data); + + close(fd); + + 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 +366,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 +386,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_SETPAG,(long)path,(long)cmarg,follow,0,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 8d0b584635..69107e5a26 100644 --- a/src/venus/fstrace.c +++ b/src/venus/fstrace.c @@ -2144,6 +2144,9 @@ 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); +#else #if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV) code = syscall(AFS_SYSCALL, call, parm0, parm1, parm2, parm3, parm4); #else @@ -2153,6 +2156,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; }