diff --git a/README b/README index 5690e27ff9..6567ef8c07 100644 --- a/README +++ b/README @@ -43,8 +43,8 @@ A Configuring i386_fbsd_42, i386_fbsd_43, i386_fbsd_44, i386_fbsd_45, i386_fbsd_46, i386_fbsd_47, i386_fbsd_50, i386_fbsd_51, i386_fbsd_52, i386_fbsd_53, i386_fbsd_60, i386_fbsd_61, - i386_fbsd_62, i386_fbsd_70 - (client does not work) + i386_fbsd_62, i386_fbsd_70, i386_fbsd_80 + (client may work on 70) i386_linux22, i386_linux24, i386_linux26 i386_nbsd15, i386_nbsd16, i386_nbsd20, i386_nbsd21, i386_nbsd30, i386_nbsd40 @@ -228,9 +228,9 @@ F OpenBSD Notes G FreeBSD Notes - The FreeBSD client does not currently work. The remaining problems - mostly have to do with locking, vnode refcounting, and packaging. The - server should work. + The FreeBSD client may now work; It is tested on 7.0 and on current + as of the commit date. + You need kernel source installed to build OpenAFS. Use the --with-bsd-kernel-headers= configure option if your kernel source is @@ -238,7 +238,10 @@ G FreeBSD Notes You also need access to your kernel build directory for the opt_global.h include file. Use the --with-bsd-kernel-build= configure option if your - kernel build is not GENERIC in the standard place. + kernel build is not GENERIC in the standard place. If + /usr/src/sys/i386/compile/GENERIC does not point to + /usr/obj/usr/src/sys/GENERIC you may need to resolve that and retry the + build. There is no server package, but I am told that "make install" will put server binaries in /usr/afs. diff --git a/src/afs/FBSD/osi_file.c b/src/afs/FBSD/osi_file.c index c7d7598093..662e4b00b0 100644 --- a/src/afs/FBSD/osi_file.c +++ b/src/afs/FBSD/osi_file.c @@ -50,7 +50,9 @@ osi_UFSOpen(afs_int32 ainode) osi_FreeSmallSpace(afile); osi_Panic("UFSOpen: igetinode failed"); } -#if defined(AFS_FBSD50_ENV) +#if defined(AFS_FBSD80_ENV) + VOP_UNLOCK(vp, 0); +#elif defined(AFS_FBSD50_ENV) VOP_UNLOCK(vp, 0, curthread); #else VOP_UNLOCK(vp, 0, curproc); @@ -71,7 +73,11 @@ afs_osi_Stat(register struct osi_file *afile, register struct osi_stat *astat) AFS_STATCNT(osi_Stat); MObtainWriteLock(&afs_xosi, 320); AFS_GUNLOCK(); -#if defined(AFS_FBSD50_ENV) +#if defined(AFS_FBSD80_ENV) + vn_lock(afile->vnode, LK_EXCLUSIVE | LK_RETRY); + code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread); + VOP_UNLOCK(afile->vnode, 0); +#elif defined(AFS_FBSD50_ENV) vn_lock(afile->vnode, LK_EXCLUSIVE | LK_RETRY, curthread); code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread); VOP_UNLOCK(afile->vnode, LK_EXCLUSIVE, curthread); @@ -105,7 +111,7 @@ osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize) { struct vattr tvattr; struct vnode *vp; - register afs_int32 code; + register afs_int32 code, glocked; AFS_STATCNT(osi_Truncate); MObtainWriteLock(&afs_xosi, 321); @@ -115,8 +121,13 @@ osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize) * have very slow truncates, even when the file is already * small enough. Check now and save some time. */ - AFS_GUNLOCK(); -#if defined(AFS_FBSD50_ENV) + glocked = ISAFS_GLOCK(); + if (glocked) + AFS_GUNLOCK(); +#if defined(AFS_FBSD80_ENV) + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread); +#elif defined(AFS_FBSD50_ENV) vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread); code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread); #else @@ -135,12 +146,15 @@ osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize) #endif out: -#if defined(AFS_FBSD50_ENV) +#if defined(AFS_FBSD80_ENV) + VOP_UNLOCK(vp, 0); +#elif defined(AFS_FBSD50_ENV) VOP_UNLOCK(vp, LK_EXCLUSIVE, curthread); #else VOP_UNLOCK(vp, LK_EXCLUSIVE, curproc); #endif - AFS_GLOCK(); + if (glocked) + AFS_GLOCK(); MReleaseWriteLock(&afs_xosi); return code; } diff --git a/src/afs/FBSD/osi_machdep.h b/src/afs/FBSD/osi_machdep.h index 55fa0d9094..bd305cf25a 100644 --- a/src/afs/FBSD/osi_machdep.h +++ b/src/afs/FBSD/osi_machdep.h @@ -59,7 +59,14 @@ #undef afs_osi_Alloc_NoSleep #define afs_osi_Alloc_NoSleep(size) osi_fbsd_alloc((size), 0) -#define VN_RELE(vp) vrele(vp) +#ifdef AFS_FBSD80_ENV +#define VN_RELE(vp) \ + do { \ + vrele(vp); \ + } while(0); +#else +#define VN_RELE(vp) vrele(vp) +#endif #define VN_HOLD(vp) VREF(vp) #ifdef AFS_FBSD60_ENV @@ -84,10 +91,8 @@ extern struct mtx afs_global_mtx; #define AFS_GLOCK() mtx_lock(&afs_global_mtx) #define AFS_GUNLOCK() mtx_unlock(&afs_global_mtx) #define ISAFS_GLOCK() (mtx_owned(&afs_global_mtx)) - #else /* FBSD50 */ extern struct lock afs_global_lock; - #define osi_curcred() (curproc->p_cred->pc_ucred) #define afs_suser(x) (!suser(curproc)) #define osi_getpid() (curproc->p_pid) diff --git a/src/afs/FBSD/osi_misc.c b/src/afs/FBSD/osi_misc.c index e1c81176ca..3f930de046 100644 --- a/src/afs/FBSD/osi_misc.c +++ b/src/afs/FBSD/osi_misc.c @@ -35,12 +35,12 @@ osi_lookupname(char *aname, enum uio_seg seg, int followlink, struct vnode **vpp) { struct nameidata n; - int flags, error, wasowned; + int flags, error, glocked; #ifdef AFS_FBSD50_ENV - wasowned = mtx_owned(&afs_global_mtx); - if (wasowned) - mtx_unlock(&afs_global_mtx); + glocked = ISAFS_GLOCK(); + if (glocked) + AFS_GUNLOCK(); #endif flags = 0; @@ -49,21 +49,30 @@ osi_lookupname(char *aname, enum uio_seg seg, int followlink, flags |= FOLLOW; else flags |= NOFOLLOW; +#ifdef AFS_FBSD80_ENV + flags |= MPSAFE; /* namei must take GIANT if needed */ +#endif NDINIT(&n, LOOKUP, flags, seg, aname, curproc); if ((error = namei(&n)) != 0) { #ifdef AFS_FBSD50_ENV - if (wasowned) - mtx_lock(&afs_global_mtx); + if (glocked) + AFS_GLOCK(); #endif return error; } *vpp = n.ni_vp; - /* should we do this? */ + /* XXX should we do this? Usually NOT (matt) */ +#if defined(AFS_FBSD80_ENV) + /*VOP_UNLOCK(n.ni_vp, 0);*/ +#elif defined(AFS_FBSD50_ENV) + VOP_UNLOCK(n.ni_vp, 0, curthread); +#else VOP_UNLOCK(n.ni_vp, 0, curproc); +#endif NDFREE(&n, NDF_ONLY_PNBUF); #ifdef AFS_FBSD50_ENV - if (wasowned) - mtx_lock(&afs_global_mtx); + if (glocked) + AFS_GLOCK(); #endif return 0; } @@ -105,18 +114,18 @@ osi_fbsd_alloc(size_t size, int dropglobal) { void *rv; #ifdef AFS_FBSD50_ENV - int wasowned; + int glocked; if (dropglobal) { - wasowned = mtx_owned(&afs_global_mtx); - if (wasowned) - mtx_unlock(&afs_global_mtx); - rv = malloc(size, M_AFS, M_WAITOK); - if (wasowned) - mtx_lock(&afs_global_mtx); + glocked = ISAFS_GLOCK(); + if (glocked) + AFS_GUNLOCK(); + rv = malloc(size, M_AFS, M_WAITOK); + if (glocked) + AFS_GLOCK(); } else #endif - rv = malloc(size, M_AFS, M_NOWAIT); + rv = malloc(size, M_AFS, M_NOWAIT); return (rv); } @@ -124,46 +133,5 @@ osi_fbsd_alloc(size_t size, int dropglobal) void osi_fbsd_free(void *p) { - - free(p, M_AFS); -} - -void -osi_AllocMoreSSpace(afs_int32 preallocs) -{ - ; -} - -void -osi_FreeLargeSpace(void *p) -{ - osi_fbsd_free(p); -} - -void -osi_FreeSmallSpace(void *p) -{ - osi_fbsd_free(p); -} - -void * -osi_AllocLargeSpace(size_t size) -{ - AFS_ASSERT_GLOCK(); - AFS_STATCNT(osi_AllocLargeSpace); - return (osi_fbsd_alloc(size, 1)); -} - -void * -osi_AllocSmallSpace(size_t size) -{ - AFS_ASSERT_GLOCK(); - AFS_STATCNT(osi_AllocSmallSpace); - return (osi_fbsd_alloc(size, 1)); -} - -void -shutdown_osinet(void) -{ - ; + free(p, M_AFS); } diff --git a/src/afs/FBSD/osi_vfsops.c b/src/afs/FBSD/osi_vfsops.c index de477b95e8..17650548e8 100644 --- a/src/afs/FBSD/osi_vfsops.c +++ b/src/afs/FBSD/osi_vfsops.c @@ -98,6 +98,11 @@ afs_omount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp, afs_globalVFS = mp; mp->vfs_bsize = 8192; vfs_getnewfsid(mp); +#ifdef AFS_FBSD70_ENV /* XXX 70? */ + MNT_ILOCK(mp); + mp->mnt_flag &= ~MNT_LOCAL; + mp->mnt_kern_flag |= MNTK_MPSAFE; /* solid steel */ +#endif mp->mnt_stat.f_iosize = 8192; if (path != NULL) @@ -109,8 +114,12 @@ afs_omount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp, strcpy(mp->mnt_stat.f_mntfromname, "AFS"); /* null terminated string "AFS" will fit, just leave it be. */ strcpy(mp->mnt_stat.f_fstypename, "afs"); +#ifdef AFS_FBSD70_ENV + MNT_IUNLOCK(mp); +#endif AFS_GUNLOCK(); afs_statfs(mp, &mp->mnt_stat, p); + return 0; } @@ -140,7 +149,9 @@ afs_unmount(struct mount *mp, int flags, THREAD_OR_PROC) * the root vnode (this is just a guess right now). * This has to be done outside the global lock. */ -#ifdef AFS_FBSD53_ENV +#if defined(AFS_FBSD80_ENV) + /* do nothing */ +#elif defined(AFS_FBSD53_ENV) vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0, p); #else vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0); @@ -184,12 +195,13 @@ afs_root(struct mount *mp, struct vnode **vpp) error = 0; } else { tryagain: +#ifndef AFS_FBSD80_ENV if (afs_globalVp) { afs_PutVCache(afs_globalVp); /* vrele() needed here or not? */ afs_globalVp = NULL; } - +#endif if (!(error = afs_InitReq(&treq, cr)) && !(error = afs_CheckInit())) { tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL); /* we really want this to stay around */ diff --git a/src/afs/FBSD/osi_vm.c b/src/afs/FBSD/osi_vm.c index 5634658476..5103891439 100644 --- a/src/afs/FBSD/osi_vm.c +++ b/src/afs/FBSD/osi_vm.c @@ -20,6 +20,12 @@ #include #include "afs/param.h" +#ifdef AFS_FBSD70_ENV +#include +#include + void + vgonel(struct vnode *vp, struct thread *td); +#endif RCSID ("$Header$"); @@ -52,7 +58,10 @@ RCSID #define VOP_GETVOBJECT(vp, objp) (*(objp) = (vp)->v_object) #endif -#ifdef AFS_FBSD50_ENV +#if defined(AFS_FBSD80_ENV) +#define lock_vnode(v) vn_lock((v), LK_EXCLUSIVE | LK_RETRY) +#define unlock_vnode(v) VOP_UNLOCK((v), 0) +#elif defined(AFS_FBSD50_ENV) #define lock_vnode(v) vn_lock((v), LK_EXCLUSIVE | LK_RETRY, curthread) #define unlock_vnode(v) VOP_UNLOCK((v), 0, curthread) #else @@ -96,23 +105,29 @@ osi_VM_FlushVCache(struct vcache *avc, int *slept) if (CheckLock(&avc->lock)) return EBUSY; + return(0); + AFS_GUNLOCK(); vp = AFSTOV(avc); +#ifndef AFS_FBSD70_ENV lock_vnode(vp); +#endif if (VOP_GETVOBJECT(vp, &obj) == 0) { VM_OBJECT_LOCK(obj); vm_object_page_remove(obj, 0, 0, FALSE); -#if 0 +#if 1 if (obj->ref_count == 0) { - vgonel(vp, curproc); simple_lock(&vp->v_interlock); + vgonel(vp, curthread); vp->v_tag = VT_AFS; SetAfsVnode(vp); } #endif VM_OBJECT_UNLOCK(obj); } +#ifndef AFS_FBSD70_ENV unlock_vnode(vp); +#endif AFS_GLOCK(); return 0; @@ -146,25 +161,31 @@ osi_VM_StoreAllSegments(struct vcache *avc) */ do { anyio = 0; +#ifdef AFS_FBSD80_ENV lock_vnode(vp); +#endif if (VOP_GETVOBJECT(vp, &obj) == 0 && (obj->flags & OBJ_MIGHTBEDIRTY)) { - /* XXX - obj locking? */ +#ifdef AFS_FBSD80_ENV unlock_vnode(vp); +#endif #ifdef AFS_FBSD50_ENV if (!vget(vp, LK_EXCLUSIVE | LK_RETRY, curthread)) { #else - if (!vget(vp, LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ, curproc)) { + if (!vget(vp, LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ, curproc)) { #endif - if (VOP_GETVOBJECT(vp, &obj) == 0) { - VM_OBJECT_LOCK(obj); - vm_object_page_clean(obj, 0, 0, OBJPC_SYNC); - VM_OBJECT_UNLOCK(obj); - anyio = 1; + if (VOP_GETVOBJECT(vp, &obj) == 0) { + VM_OBJECT_LOCK(obj); + vm_object_page_clean(obj, 0, 0, OBJPC_SYNC); + VM_OBJECT_UNLOCK(obj); + anyio = 1; + } + vput(vp); } - vput(vp); } - } else - unlock_vnode(vp); +#ifdef AFS_FBSD80_ENV + else + unlock_vnode(vp); +#endif } while (anyio && (--tries > 0)); AFS_GLOCK(); ObtainWriteLock(&avc->lock, 94); @@ -184,52 +205,44 @@ osi_VM_TryToSmush(struct vcache *avc, struct AFS_UCRED *acred, int sync) { struct vnode *vp; struct vm_object *obj; - int anyio, tries; + int anyio, tries, code; + + SPLVAR; - ReleaseWriteLock(&avc->lock); - AFS_GUNLOCK(); - tries = 5; vp = AFSTOV(avc); - do { - anyio = 0; - lock_vnode(vp); - /* See the comments above. */ - if (VOP_GETVOBJECT(vp, &obj) == 0 && (obj->flags & OBJ_MIGHTBEDIRTY)) { - /* XXX - obj locking */ - unlock_vnode(vp); -#ifdef AFS_FBSD50_ENV - if (!vget(vp, LK_EXCLUSIVE | LK_RETRY, curthread)) { -#else - if (!vget(vp, LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ, curproc)) { -#endif - if (VOP_GETVOBJECT(vp, &obj) == 0) { - VM_OBJECT_LOCK(obj); - /* - * Do we really want OBJPC_SYNC? OBJPC_INVAL would be - * faster, if invalidation is really what we are being - * asked to do. (It would make more sense, too, since - * otherwise this function is practically identical to - * osi_VM_StoreAllSegments().) -GAW - */ - vm_object_page_clean(obj, 0, 0, OBJPC_SYNC); - VM_OBJECT_UNLOCK(obj); - anyio = 1; - } - vput(vp); - } - } else - unlock_vnode(vp); - } while (anyio && (--tries > 0)); - lock_vnode(vp); - if (VOP_GETVOBJECT(vp, &obj) == 0) { - VM_OBJECT_LOCK(obj); - vm_object_page_remove(obj, 0, 0, FALSE); - VM_OBJECT_UNLOCK(obj); + + if (vp->v_iflag & VI_DOOMED) { + USERPRI; + return 0; } - unlock_vnode(vp); - /*vinvalbuf(AFSTOV(avc),0, NOCRED, curproc, 0,0); */ - AFS_GLOCK(); - ObtainWriteLock(&avc->lock, 59); + + if (vp->v_bufobj.bo_object != NULL) { + VM_OBJECT_LOCK(vp->v_bufobj.bo_object); + /* + * Do we really want OBJPC_SYNC? OBJPC_INVAL would be + * faster, if invalidation is really what we are being + * asked to do. (It would make more sense, too, since + * otherwise this function is practically identical to + * osi_VM_StoreAllSegments().) -GAW + */ + + /* + * Dunno. We no longer resemble osi_VM_StoreAllSegments, + * though maybe that's wrong, now. And OBJPC_SYNC is the + * common thing in 70 file systems, it seems. Matt. + */ + + vm_object_page_clean(vp->v_bufobj.bo_object, 0, 0, OBJPC_SYNC); + VM_OBJECT_UNLOCK(vp->v_bufobj.bo_object); + } + + tries = 5; + code = vinvalbuf(vp, V_SAVE, curthread, PCATCH, 0); + while (code && (tries > 0)) { + code = vinvalbuf(vp, V_SAVE, curthread, PCATCH, 0); + --tries; + } + USERPRI; } /* Purge VM for a file when its callback is revoked. diff --git a/src/afs/FBSD/osi_vnodeops.c b/src/afs/FBSD/osi_vnodeops.c index a02fe77361..324c42a755 100644 --- a/src/afs/FBSD/osi_vnodeops.c +++ b/src/afs/FBSD/osi_vnodeops.c @@ -95,6 +95,11 @@ static vop_setattr_t afs_vop_setattr; static vop_strategy_t afs_vop_strategy; static vop_symlink_t afs_vop_symlink; static vop_write_t afs_vop_write; +#if defined(AFS_FBSD70_ENV) && !defined(AFS_FBSD90_ENV) +static vop_lock1_t afs_vop_lock; +static vop_unlock_t afs_vop_unlock; +static vop_islocked_t afs_vop_islocked; +#endif struct vop_vector afs_vnodeops = { .vop_default = &default_vnodeops, @@ -128,6 +133,11 @@ struct vop_vector afs_vnodeops = { .vop_strategy = afs_vop_strategy, .vop_symlink = afs_vop_symlink, .vop_write = afs_vop_write, +#if defined(AFS_FBSD70_ENV) && !defined(AFS_FBSD90_ENV) + .vop_lock1 = afs_vop_lock, + .vop_unlock = afs_vop_unlock, + .vop_islocked = afs_vop_islocked, +#endif }; #else /* AFS_FBSD60_ENV */ @@ -213,6 +223,11 @@ struct vnodeopv_entry_desc afs_vnodeop_entries[] = { {&vop_write_desc, (vop_t *) afs_vop_write}, /* write */ {&vop_ioctl_desc, (vop_t *) afs_vop_ioctl}, /* XXX ioctl */ /*{ &vop_seek_desc, afs_vop_seek }, *//* seek */ +#if defined(AFS_FBSD70_ENV) && !defined(AFS_FBSD90_ENV) + {&vop_lock1_desc, (vop_t *) afs_vop_lock}, /* lock */ + {&vop_unlock_desc, (vop_t *) afs_vop_unlock}, /* unlock */ + {&vop_islocked_desc, (vop_t *) afs_vop_islocked}, /* islocked */ +#endif {NULL, NULL} }; struct vnodeopv_desc afs_vnodeop_opv_desc = @@ -233,6 +248,123 @@ struct vnodeopv_desc afs_vnodeop_opv_desc = #define a_p a_td #endif +#if defined(AFS_FBSD80_ENV) +#define ma_vn_lock(vp, flags, p) (vn_lock(vp, flags)) +#define MA_VOP_LOCK(vp, flags, p) (VOP_LOCK(vp, flags)) +#define MA_VOP_UNLOCK(vp, flags, p) (VOP_UNLOCK(vp, flags)) +#else +#define ma_vn_lock(vp, flags, p) (vn_lock(vp, flags, p)) +#define MA_VOP_LOCK(vp, flags, p) (VOP_LOCK(vp, flags, p)) +#define MA_VOP_UNLOCK(vp, flags, p) (VOP_UNLOCK(vp, flags, p)) +#endif + +#ifdef AFS_FBSD70_ENV +#ifndef AFS_FBSD80_ENV +/* From kern_lock.c */ +#define COUNT(td, x) if ((td)) (td)->td_locks += (x) +#define LK_ALL (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE | \ + LK_SHARE_NONZERO | LK_WAIT_NONZERO) + +static __inline void +sharelock(struct thread *td, struct lock *lkp, int incr) { + lkp->lk_flags |= LK_SHARE_NONZERO; + lkp->lk_sharecount += incr; + COUNT(td, incr); +} +#endif + +/* + * Standard lock, unlock and islocked functions. + */ +int +afs_vop_lock(ap) + struct vop_lock1_args /* { + struct vnode *a_vp; + int a_flags; + struct thread *a_td; + char *file; + int line; + } */ *ap; +{ + struct vnode *vp = ap->a_vp; + struct lock *lkp = vp->v_vnlock; + +#if 0 && defined(AFS_FBSD80_ENV) && !defined(UKERNEL) + afs_warn("afs_vop_lock: tid %d pid %d \"%s\"\n", curthread->td_tid, + curthread->td_proc->p_pid, curthread->td_name); + kdb_backtrace(); +#endif + +#ifdef AFS_FBSD80_ENV + return (_lockmgr_args(lkp, ap->a_flags, VI_MTX(vp), + LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, + ap->a_file, ap->a_line)); +#else + return (_lockmgr(lkp, ap->a_flags, VI_MTX(vp), ap->a_td, ap->a_file, ap->a_line)); +#endif +} + +/* See above. */ +int +afs_vop_unlock(ap) + struct vop_unlock_args /* { + struct vnode *a_vp; + int a_flags; + struct thread *a_td; + } */ *ap; +{ + struct vnode *vp = ap->a_vp; + struct lock *lkp = vp->v_vnlock; + +#ifdef AFS_FBSD80_ENV + int code; + u_int op; + op = ((ap->a_flags) | LK_RELEASE) & LK_TYPE_MASK; + int glocked = ISAFS_GLOCK(); + if (glocked) + AFS_GUNLOCK(); + if ((op & (op - 1)) != 0) { + afs_warn("afs_vop_unlock: Shit.\n"); + goto done; + } + code = lockmgr(lkp, ap->a_flags | LK_RELEASE, VI_MTX(vp)); + done: + if (glocked) + AFS_GLOCK(); + return(code); +#else + /* possibly in current code path where this + * forces trace, we should have had a (shared? not + * necessarily, see _lockmgr in kern_lock.c) lock + * and that's the real bug. but. + */ + critical_enter(); + if ((lkp->lk_exclusivecount == 0) && + (!(lkp->lk_flags & LK_SHARE_NONZERO))) { + sharelock(ap->a_td, lkp, 1); + } + critical_exit(); + return (lockmgr(lkp, ap->a_flags | LK_RELEASE, VI_MTX(vp), + ap->a_td)); +#endif +} + +/* See above. */ +int +afs_vop_islocked(ap) + struct vop_islocked_args /* { + struct vnode *a_vp; + struct thread *a_td; (not in 80) + } */ *ap; +{ +#ifdef AFS_FBSD80_ENV + return (lockstatus(ap->a_vp->v_vnlock)); +#else + return (lockstatus(ap->a_vp->v_vnlock, ap->a_td)); +#endif +} +#endif /* 70 */ + /* * Mosty copied from sys/ufs/ufs/ufs_vnops.c:ufs_pathconf(). * We should know the correct answers to these questions with @@ -346,25 +478,39 @@ afs_vop_lookup(ap) #else struct proc *p = ap->a_cnp->cn_proc; #endif + + dvp = ap->a_dvp; + if (dvp->v_type != VDIR) { +#ifndef AFS_FBSD70_ENV + *ap->a_vpp = 0; +#endif + return ENOTDIR; + } + + if ((flags & ISDOTDOT) && (dvp->v_vflag & VV_ROOT)) + return EIO; + GETNAME(); lockparent = flags & LOCKPARENT; wantparent = flags & (LOCKPARENT | WANTPARENT); - if (ap->a_dvp->v_type != VDIR) { - *ap->a_vpp = 0; - DROPNAME(); - return ENOTDIR; - } - dvp = ap->a_dvp; +#ifdef AFS_FBSD80_ENV + cnp->cn_flags |= MPSAFE; /* steel */ +#endif + +#ifndef AFS_FBSD70_ENV if (flags & ISDOTDOT) VOP_UNLOCK(dvp, 0, p); +#endif + AFS_GLOCK(); error = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred); AFS_GUNLOCK(); + if (error) { if (flags & ISDOTDOT) - VOP_LOCK(dvp, LK_EXCLUSIVE | LK_RETRY, p); + MA_VOP_LOCK(dvp, LK_EXCLUSIVE | LK_RETRY, p); if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) && (flags & ISLASTCN) && error == ENOENT) error = EJUSTRETURN; @@ -381,10 +527,10 @@ afs_vop_lookup(ap) * we also always return the vnode locked. */ if (flags & ISDOTDOT) { - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + ma_vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); /* always return the child locked */ if (lockparent && (flags & ISLASTCN) - && (error = vn_lock(dvp, LK_EXCLUSIVE, p))) { + && (error = ma_vn_lock(dvp, LK_EXCLUSIVE, p))) { vput(vp); DROPNAME(); return (error); @@ -393,9 +539,12 @@ afs_vop_lookup(ap) /* they're the same; afs_lookup() already ref'ed the leaf. * It came in locked, so we don't need to ref OR lock it */ } else { - if (!lockparent || !(flags & ISLASTCN)) - VOP_UNLOCK(dvp, 0, p); /* done with parent. */ - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + if (!lockparent || !(flags & ISLASTCN)) { +#ifndef AFS_FBSD70_ENV /* 6 too? */ + MA_VOP_UNLOCK(dvp, 0, p); /* done with parent. */ +#endif + } + ma_vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); /* always return the child locked */ } *ap->a_vpp = vp; @@ -440,7 +589,7 @@ afs_vop_create(ap) if (vcp) { *ap->a_vpp = AFSTOV(vcp); - vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, p); + ma_vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, p); } else *ap->a_vpp = 0; @@ -747,7 +896,7 @@ afs_vop_getpages(struct vop_getpages_args *ap) */ if (!code) { #if defined(AFS_FBSD70_ENV) - if(0) /* XXXX fixme for 7.0 */ + if (m->oflags & VPO_WANTED) #else if (m->flags & PG_WANTED) #endif @@ -1012,14 +1161,14 @@ afs_vop_link(ap) error = EISDIR; goto out; } - if ((error = vn_lock(vp, LK_EXCLUSIVE, p)) != 0) { + if ((error = ma_vn_lock(vp, LK_EXCLUSIVE, p)) != 0) { goto out; } AFS_GLOCK(); error = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred); AFS_GUNLOCK(); if (dvp != vp) - VOP_UNLOCK(vp, 0, p); + MA_VOP_UNLOCK(vp, 0, p); out: DROPNAME(); return error; @@ -1108,7 +1257,7 @@ afs_vop_rename(ap) vput(fvp); return (error); } - if ((error = vn_lock(fvp, LK_EXCLUSIVE, p)) != 0) + if ((error = ma_vn_lock(fvp, LK_EXCLUSIVE, p)) != 0) goto abortit; MALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK); @@ -1171,7 +1320,7 @@ afs_vop_mkdir(ap) } if (vcp) { *ap->a_vpp = AFSTOV(vcp); - vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, p); + ma_vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, p); } else *ap->a_vpp = 0; DROPNAME(); @@ -1226,9 +1375,9 @@ afs_vop_symlink(struct vop_symlink_args *ap) if (error == 0) { newvp = AFSTOV(vcp); #ifdef AFS_FBSD50_ENV - vn_lock(newvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_thread); + ma_vn_lock(newvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_thread); #else - vn_lock(newvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_proc); + ma_vn_lock(newvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_proc); #endif } } @@ -1321,7 +1470,9 @@ afs_vop_inactive(ap) AFS_GLOCK(); afs_InactiveVCache(VTOAFS(vp), 0); /* decrs ref counts */ AFS_GUNLOCK(); - VOP_UNLOCK(vp, 0, ap->a_p); +#ifndef AFS_FBSD80_ENV + MA_VOP_UNLOCK(vp, 0, ap->a_p); +#endif return 0; } @@ -1362,8 +1513,13 @@ afs_vop_reclaim(struct vop_reclaim_args *ap) if (code) printf("afs_vop_reclaim: afs_FlushVCache failed code %d\n", code); #ifdef AFS_FBSD60_ENV - else + else { vnode_destroy_vobject(vp); +#ifndef AFS_FBSD70_ENV + vfs_hash_remove(vp); +#endif + vp->v_data = 0; + } #endif return 0; } diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index fa2727f7c3..2d85f83644 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -1232,8 +1232,6 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED afs_InitFakeStat(&fakestate); AFS_DISCON_LOCK(); - - /*printf("Looking up %s\n", aname);*/ if ((code = afs_InitReq(&treq, acred))) goto done; @@ -1431,7 +1429,9 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED if (tvc) { if (no_read_access && vType(tvc) != VDIR && vType(tvc) != VLNK) { /* need read access on dir to stat non-directory / non-link */ +#ifndef AFS_FBSD80_ENV afs_PutVCache(tvc); +#endif *avcp = NULL; code = EACCES; goto done; @@ -1588,7 +1588,9 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED /* if the vcache isn't usable, release it */ if (tvc && !(tvc->states & CStatd)) { - afs_PutVCache(tvc); +#ifndef AFS_FBSD80_ENV + afs_PutVCache(tvc); +#endif tvc = NULL; } } else { @@ -1651,7 +1653,9 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED ReleaseWriteLock(&tvc->lock); if (code) { +#ifndef AFS_FBSD80_ENV afs_PutVCache(tvc); +#endif if (tvolp) afs_PutVolume(tvolp, WRITE_LOCK); goto done; @@ -1673,7 +1677,9 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED } else { tvc = afs_GetVCache(tvc->mvid, &treq, NULL, NULL); } +#ifndef AFS_FBSD80_ENV afs_PutVCache(uvc); /* we're done with it */ +#endif if (!tvc) { code = ENOENT; @@ -1698,7 +1704,9 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED afs_PutVolume(tvolp, WRITE_LOCK); } } else { +#ifndef AFS_FBSD80_ENV afs_PutVCache(tvc); +#endif code = ENOENT; if (tvolp) afs_PutVolume(tvolp, WRITE_LOCK); diff --git a/src/afs/VNOPS/afs_vnop_read.c b/src/afs/VNOPS/afs_vnop_read.c index 7ffbc6df3f..0e82f5b947 100644 --- a/src/afs/VNOPS/afs_vnop_read.c +++ b/src/afs/VNOPS/afs_vnop_read.c @@ -903,6 +903,12 @@ afs_UFSRead(register struct vcache *avc, struct uio *auio, code = VOP_READ(tfile->vnode, &tuio, 0, afs_osi_credp); VOP_UNLOCK(tfile->vnode, 0, current_proc()); AFS_GLOCK(); +#elif defined(AFS_FBSD80_ENV) + AFS_GUNLOCK(); + VOP_LOCK(tfile->vnode, LK_EXCLUSIVE); + code = VOP_READ(tfile->vnode, &tuio, 0, afs_osi_credp); + VOP_UNLOCK(tfile->vnode, 0); + AFS_GLOCK(); #elif defined(AFS_FBSD50_ENV) AFS_GUNLOCK(); VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, curthread); diff --git a/src/afs/VNOPS/afs_vnop_write.c b/src/afs/VNOPS/afs_vnop_write.c index 8f467e26f1..7ba255b5a8 100644 --- a/src/afs/VNOPS/afs_vnop_write.c +++ b/src/afs/VNOPS/afs_vnop_write.c @@ -613,6 +613,12 @@ afs_UFSWrite(register struct vcache *avc, struct uio *auio, int aio, code = VOP_WRITE(tfile->vnode, &tuio, 0, afs_osi_credp); VOP_UNLOCK(tfile->vnode, 0, current_proc()); AFS_GLOCK(); +#elif defined(AFS_FBSD80_ENV) + AFS_GUNLOCK(); + VOP_LOCK(tfile->vnode, LK_EXCLUSIVE); + code = VOP_WRITE(tfile->vnode, &tuio, 0, afs_osi_credp); + VOP_UNLOCK(tfile->vnode, 0); + AFS_GLOCK(); #elif defined(AFS_FBSD50_ENV) AFS_GUNLOCK(); VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, curthread); diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index 1316f91ed6..64ed5cfa80 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -515,8 +515,14 @@ afs_GetDownD(int anumber, int *aneedSpace, afs_int32 buckethint) afs_uint32 maxVictimPtr; /* where it is */ int discard; int curbucket; + int vfslocked; + +#if defined(AFS_FBSD80_ENV) && !defined(UKERNEL) + vfslocked = VFS_LOCK_GIANT(afs_globalVFS); +#endif AFS_STATCNT(afs_GetDownD); + if (CheckLock(&afs_xdcache) != -1) osi_Panic("getdownd nolock"); /* decrement anumber first for all dudes in free list */ @@ -524,9 +530,14 @@ afs_GetDownD(int anumber, int *aneedSpace, afs_int32 buckethint) * because we should try to free space even if anumber <=0 */ if (!aneedSpace || *aneedSpace <= 0) { anumber -= afs_freeDCCount; - if (anumber <= 0) + if (anumber <= 0) { +#if defined(AFS_FBSD80_ENV) && !defined(UKERNEL) + VFS_UNLOCK_GIANT(vfslocked); +#endif return; /* enough already free */ + } } + /* bounds check parameter */ if (anumber > MAXATONCE) anumber = MAXATONCE; /* all we can do */ @@ -799,6 +810,11 @@ afs_GetDownD(int anumber, int *aneedSpace, afs_int32 buckethint) break; } } /* big while loop */ + +#if defined(AFS_FBSD80_ENV) && !defined(UKERNEL) + VFS_UNLOCK_GIANT(vfslocked); +#endif + return; } /*afs_GetDownD */ diff --git a/src/afs/afs_osi.c b/src/afs/afs_osi.c index ea304954b4..79493ef767 100644 --- a/src/afs/afs_osi.c +++ b/src/afs/afs_osi.c @@ -91,6 +91,11 @@ osi_Init(void) usimple_lock_init(&afs_global_lock); afs_global_owner = (thread_t) 0; #elif defined(AFS_FBSD50_ENV) +#if defined(AFS_FBSD80_ENV) && defined(WITNESS) + /* "lock_initalized" (sic) can panic, checks a flag bit + * is unset _before_ init */ + memset(&afs_global_mtx, 0, sizeof(struct mtx)); +#endif mtx_init(&afs_global_mtx, "AFS global lock", NULL, MTX_DEF); #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) #if !defined(AFS_DARWIN80_ENV) diff --git a/src/afs/afs_osi_alloc.c b/src/afs/afs_osi_alloc.c index 91ad583ed6..6773316dfa 100644 --- a/src/afs/afs_osi_alloc.c +++ b/src/afs/afs_osi_alloc.c @@ -19,7 +19,7 @@ RCSID #include "afsincludes.h" /* Afs-based standard headers */ #include "afs/afs_stats.h" /* afs statistics */ -#ifndef AFS_FBSD_ENV + #ifdef AFS_AIX41_ENV #include "sys/lockl.h" @@ -257,4 +257,4 @@ shutdown_osinet(void) afs_stats_cmperf.SmallBlocksActive); } } -#endif + diff --git a/src/afs/afs_osi_vm.c b/src/afs/afs_osi_vm.c index 4aac5232be..74aa51c0b4 100644 --- a/src/afs/afs_osi_vm.c +++ b/src/afs/afs_osi_vm.c @@ -49,6 +49,7 @@ osi_Active(register struct vcache *avc) void osi_FlushPages(register struct vcache *avc, struct AFS_UCRED *credp) { + int vfslocked; afs_hyper_t origDV; ObtainReadLock(&avc->lock); /* If we've already purged this version, or if we're the ones @@ -79,9 +80,19 @@ osi_FlushPages(register struct vcache *avc, struct AFS_UCRED *credp) ICL_TYPE_INT32, origDV.low, ICL_TYPE_INT32, avc->m.Length); ReleaseWriteLock(&avc->lock); +#ifdef AFS_FBSD70_ENV + vfslocked = VFS_LOCK_GIANT(AFSTOV(avc)->v_mount); +#endif +#ifndef AFS_FBSD70_ENV AFS_GUNLOCK(); +#endif osi_VM_FlushPages(avc, credp); +#ifndef AFS_FBSD70_ENV AFS_GLOCK(); +#endif +#ifdef AFS_FBSD70_ENV + VFS_UNLOCK_GIANT(vfslocked); +#endif ObtainWriteLock(&avc->lock, 88); /* do this last, and to original version, since stores may occur diff --git a/src/afs/afs_osidnlc.c b/src/afs/afs_osidnlc.c index e01e5a1732..82704a34ae 100644 --- a/src/afs/afs_osidnlc.c +++ b/src/afs/afs_osidnlc.c @@ -63,6 +63,14 @@ int dnlct; #define dnlcHash(ts, hval) for (hval=0; *ts; ts++) { hval *= 173; hval += *ts; } +#if defined(AFS_FBSD80_ENV) && !defined(UKERNEL) +#define ma_critical_enter critical_enter +#define ma_critical_exit critical_exit +#else +#define ma_critical_enter() {} +#define ma_critical_exit() {} +#endif + static struct nc * GetMeAnEntry(void) { @@ -201,12 +209,17 @@ osi_dnlc_lookup(struct vcache *adp, char *aname, int locktype) vnode_t tvp; #endif - if (!afs_usednlc) - return 0; + ma_critical_enter(); + + if (!afs_usednlc) { + ma_critical_exit(); + return 0; + } dnlcHash(ts, key); /* leaves ts pointing at the NULL */ if (ts - aname >= AFSNCNAMESIZE) { - return 0; + ma_critical_exit(); + return 0; } skey = key & (NHSIZE - 1); @@ -231,6 +244,7 @@ osi_dnlc_lookup(struct vcache *adp, char *aname, int locktype) ReleaseReadLock(&afs_xdnlc); ReleaseReadLock(&afs_xvcache); osi_dnlc_purge(); + ma_critical_exit(); return (0); } } @@ -251,6 +265,7 @@ osi_dnlc_lookup(struct vcache *adp, char *aname, int locktype) ReleaseReadLock(&afs_xvcache); dnlcstats.misses++; osi_dnlc_remove(adp, aname, tvc); + ma_critical_exit(); return 0; } #ifdef AFS_OSF_ENV @@ -262,6 +277,7 @@ osi_dnlc_lookup(struct vcache *adp, char *aname, int locktype) ReleaseReadLock(&afs_xvcache); dnlcstats.misses++; osi_dnlc_remove(adp, aname, tvc); + ma_critical_exit(); return 0; } if (vnode_ref(tvp)) { @@ -271,10 +287,18 @@ osi_dnlc_lookup(struct vcache *adp, char *aname, int locktype) AFS_GLOCK(); dnlcstats.misses++; osi_dnlc_remove(adp, aname, tvc); + ma_critical_exit(); return 0; } #else +#ifdef AFS_FBSD50_ENV + /* can't sleep in a critical section */ + ma_critical_exit(); osi_vnhold(tvc, 0); + ma_critical_enter(); +#else + osi_vnhold(tvc, 0); +#endif /* AFS_FBSD80_ENV */ #endif #endif ReleaseReadLock(&afs_xvcache); @@ -313,6 +337,7 @@ osi_dnlc_lookup(struct vcache *adp, char *aname, int locktype) #endif } + ma_critical_exit(); return tvc; } diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 9f33f88e23..59b585bc97 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -1122,6 +1122,11 @@ restart: insmntque(tvc, afs_globalVFS); #endif /* AFS_OSF_ENV */ #endif /* AFS_DUX40_ENV */ +#ifdef AFS_FBSD70_ENV +#ifndef AFS_FBSD80_ENV /* yup. they put it back. */ + insmntque(AFSTOV(tvc), afs_globalVFS); +#endif +#endif #if defined(AFS_SGI_ENV) VN_SET_DPAGES(&(tvc->v), (struct pfdat *)NULL); osi_Assert((tvc->v.v_flag & VINACT) == 0); @@ -1822,6 +1827,20 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq, ObtainWriteLock(&tvc->lock, 954); if (!iheldthelock) VOP_UNLOCK(vp, LK_EXCLUSIVE, current_proc()); +#elif defined(AFS_FBSD80_ENV) + iheldthelock = VOP_ISLOCKED(vp); + if (!iheldthelock) { + /* nosleep/sleep lock order reversal */ + int glocked = ISAFS_GLOCK(); + if (glocked) + AFS_GUNLOCK(); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + if (glocked) + AFS_GLOCK(); + } + vinvalbuf(vp, V_SAVE, curthread, PINOD, 0); + if (!iheldthelock) + VOP_UNLOCK(vp, 0); #elif defined(AFS_FBSD60_ENV) iheldthelock = VOP_ISLOCKED(vp, curthread); if (!iheldthelock) diff --git a/src/config/afs_sysnames.h b/src/config/afs_sysnames.h index dd44c2fc57..890987ae3b 100644 --- a/src/config/afs_sysnames.h +++ b/src/config/afs_sysnames.h @@ -186,6 +186,7 @@ #define SYS_NAME_ID_i386_fbsd_61 2113 #define SYS_NAME_ID_i386_fbsd_62 2114 #define SYS_NAME_ID_i386_fbsd_70 2115 +#define SYS_NAME_ID_i386_fbsd_80 2116 #define SYS_NAME_ID_ia64_linux2 2200 #define SYS_NAME_ID_ia64_linux22 2201 diff --git a/src/config/param.i386_fbsd_80.h b/src/config/param.i386_fbsd_80.h new file mode 100644 index 0000000000..ce5f0f3005 --- /dev/null +++ b/src/config/param.i386_fbsd_80.h @@ -0,0 +1,214 @@ +#ifndef AFS_PARAM_H +#define AFS_PARAM_H + +/* Machine / Operating system information */ +#define SYS_NAME "i386_fbsd_80" +#define SYS_NAME_ID SYS_NAME_ID_i386_fbsd_80 + +#define AFSLITTLE_ENDIAN 1 +#define AFS_HAVE_FFS 1 /* Use system's ffs. */ +#define AFS_HAVE_STATVFS 1 /* System doesn't support statvfs */ +#define AFS_VM_RDWR_ENV 1 /* read/write implemented via VM */ + + +#ifndef UKERNEL +/* This section for kernel libafs compiles only */ + +#ifndef IGNORE_STDS_H +#include +#endif + +#define AFS_XBSD_ENV 1 /* {Free,Open,Net}BSD */ +#define AFS_X86_XBSD_ENV 1 + +#define AFS_NAMEI_ENV 1 /* User space interface to file system */ +#define AFS_64BIT_ENV 1 +#define AFS_64BIT_CLIENT 1 +#define AFS_64BIT_IOPS_ENV 1 /* Needed for NAMEI */ +#define AFS_FBSD_ENV 1 +#define AFS_FBSD40_ENV 1 +#define AFS_FBSD42_ENV 1 +#define AFS_FBSD43_ENV 1 +#define AFS_FBSD44_ENV 1 +#define AFS_FBSD45_ENV 1 +#define AFS_FBSD46_ENV 1 +#define AFS_FBSD47_ENV 1 +#define AFS_FBSD50_ENV 1 +#define AFS_FBSD51_ENV 1 +#define AFS_FBSD52_ENV 1 +#define AFS_FBSD53_ENV 1 +#define AFS_FBSD60_ENV 1 +#define AFS_FBSD61_ENV 1 +#define AFS_FBSD62_ENV 1 +#define AFS_FBSD70_ENV 1 +#define AFS_FBSD80_ENV 1 +#define AFS_X86_FBSD_ENV 1 +#define AFS_X86_FBSD40_ENV 1 +#define AFS_X86_FBSD42_ENV 1 +#define AFS_X86_FBSD43_ENV 1 +#define AFS_X86_FBSD46_ENV 1 +#define AFS_X86_FBSD47_ENV 1 +#define AFS_X86_FBSD50_ENV 1 +#define AFS_X86_FBSD60_ENV 1 /* added at 70--ie, some changes should port <-- */ +#define AFS_X86_FBSD62_ENV 1 +#define AFS_X86_FBSD70_ENV 1 +#define AFS_X86_FBSD80_ENV 1 +#define AFS_X86_ENV 1 +#define AFS_NONFSTRANS 1 +#define FTRUNC O_TRUNC + +#define IUPD 0x0010 +#define IACC 0x0020 +#define ICHG 0x0040 +#define IMOD 0x0080 + +#define IN_LOCK(ip) lockmgr(&ip->i_lock, LK_EXCLUSIVE, \ + NULL, curproc) +#define IN_UNLOCK(ip) lockmgr(&ip->i_lock, LK_RELEASE, \ + NULL, curproc) + +#include + +#define AFS_VFS_ENV 1 +#define AFS_VFSINCL_ENV 1 +#define AFS_GREEDY43_ENV 1 +#define AFS_ENV 1 + +#define AFS_SYSCALL 339 +#define AFS_MOUNT_AFS "afs" + +#ifndef MOUNT_UFS +#define MOUNT_UFS "ufs" +#endif + +#ifndef MOUNT_AFS +#define MOUNT_AFS AFS_MOUNT_AFS +#endif + +#define RXK_LISTENER_ENV 1 +#define AFS_GCPAGS 0 /* if nonzero, garbage collect PAGs */ +#define AFS_USE_GETTIMEOFDAY 1 /* use gettimeofday to implement rx clock */ + +/* Extra kernel definitions (from kdefs file) */ +#ifdef _KERNEL +#define AFS_GLOBAL_SUNLOCK 1 +#define AFS_VFS34 1 /* What is VFS34??? */ +#define AFS_SHORTGID 0 /* are group id's short? */ +#define afsio_iov uio_iov +#define afsio_iovcnt uio_iovcnt +#define afsio_offset uio_offset +#define afsio_seg uio_segflg +#define afsio_resid uio_resid +#define AFS_UIOSYS UIO_SYSSPACE +#define AFS_UIOUSER UIO_USERSPACE +#define AFS_CLBYTES CLBYTES +#define osi_GetTime(x) microtime(x) +#define AFS_KALLOC(x) osi_fbsd_alloc((x), 1) +#undef AFS_KALLOC_NOSLEEP +#define AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0) +#define AFS_KFREE(x,y) osi_fbsd_free((x)) +#define v_count v_usecount +#define v_vfsp v_mount +#define vfs_bsize mnt_stat.f_bsize +#define vfs_fsid mnt_stat.f_fsid +#define va_nodeid va_fileid +#define vfs_vnodecovered mnt_vnodecovered +#define direct dirent +#define vnode_t struct vnode + +#ifndef MUTEX_DEFAULT +#define MUTEX_DEFAULT 0 +#endif /* MUTEX_DEFAULT */ + +#ifndef SSYS +#define SSYS 0x00002 +#endif /* SSYS */ + +#define p_rcred p_ucred + +#if !defined(ASSEMBLER) && !defined(__LANGUAGE_ASSEMBLY__) +enum vcexcl { NONEXCL, EXCL }; + +#ifdef KERNEL +#ifndef MIN +#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#endif +#ifndef MAX +#define MAX(A,B) ((A) > (B) ? (A) : (B)) +#endif +#endif /* KERNEL */ + +#endif /* ! ASSEMBLER & ! __LANGUAGE_ASSEMBLY__ */ +#endif /* _KERNEL */ + +#else /* !defined(UKERNEL) */ + +/* This section for user space compiles only */ + +#define UKERNEL 1 /* user space kernel */ +#define AFS_ENV 1 +#define AFS_VFSINCL_ENV 1 +#define AFS_USR_FBSD40_ENV 1 +#define AFS_USR_FBSD42_ENV 1 +#define AFS_USR_FBSD43_ENV 1 +#define AFS_USR_FBSD44_ENV 1 +#define AFS_USR_FBSD45_ENV 1 +#define AFS_USR_FBSD46_ENV 1 +#define AFS_USR_FBSD47_ENV 1 +#define AFS_USR_FBSD50_ENV 1 +#define AFS_USR_FBSD51_ENV 1 +#define AFS_USR_FBSD52_ENV 1 +#define AFS_USR_FBSD53_ENV 1 +#define AFS_USR_FBSD60_ENV 1 +#define AFS_USR_FBSD61_ENV 1 +#define AFS_USR_FBSD70_ENV 1 +#define AFS_USR_FBSD80_ENV 1 +#define AFS_USR_FBSD_ENV 1 +#define AFS_NONFSTRANS 1 + +#define AFS_MOUNT_AFS "afs" /* The name of the filesystem type. */ +#define AFS_SYSCALL 339 +#define AFS_NAMEI_ENV 1 /* User space interface to file system */ +#define AFS_64BIT_ENV 1 +#define AFS_64BIT_IOPS_ENV 1 /* Needed for NAMEI */ +#define AFS_USERSPACE_IP_ADDR 1 +#define RXK_LISTENER_ENV 1 +#define AFS_GCPAGS 0 /* if nonzero, garbage collect PAGs */ + +#include + +#define afsio_iov uio_iov +#define afsio_iovcnt uio_iovcnt +#define afsio_offset uio_offset +#define afsio_seg uio_segflg +#define afsio_fmode uio_fmode +#define afsio_resid uio_resid +#define AFS_UIOSYS 1 +#define AFS_UIOUSER UIO_USERSPACE +#define AFS_CLBYTES MCLBYTES +#define AFS_MINCHANGE 2 +#define VATTR_NULL usr_vattr_null + +#define AFS_DIRENT +#ifndef CMSERVERPREF +#define CMSERVERPREF +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* !defined(UKERNEL) */ + +/* general user-space compiles */ + +#if defined(UKERNEL) || !defined(KERNEL) +#define STDLIB_HAS_MALLOC_PROTOS 1 +#endif + +#endif /* AFS_PARAM_H */ diff --git a/src/libafs/MakefileProto.FBSD.in b/src/libafs/MakefileProto.FBSD.in index bf0310a62e..98e9411c1f 100644 --- a/src/libafs/MakefileProto.FBSD.in +++ b/src/libafs/MakefileProto.FBSD.in @@ -76,7 +76,11 @@ setup: -ln -fs ${KSRC}/@HOST_CPU@/include machine -ln -fs ${KSRC}/netinet netinet -ln -fs ${KSRC}/nfs nfs + -ln -fs /usr/include/rpc rpc + + -ln -fs ${KSRC}/rpc rpc + -ln -fs ${KSRC}/sys sys -ln -fs ${KSRC}/ufs/ufs ufs -ln -fs ${KSRC}/sys h diff --git a/src/libuafs/MakefileProto.FBSD.in b/src/libuafs/MakefileProto.FBSD.in index fb74c89c7e..9c16e28738 100644 --- a/src/libuafs/MakefileProto.FBSD.in +++ b/src/libuafs/MakefileProto.FBSD.in @@ -23,9 +23,9 @@ OPTF=-O TEST_CFLAGS=-D_REENTRANT -DAFS_PTHREAD_ENV -DAFS_FBSD40_ENV TEST_LDFLAGS= - + TEST_LIBS=-lc_r - + TEST_LIBS=-lpthread diff --git a/src/rx/FBSD/rx_kmutex.h b/src/rx/FBSD/rx_kmutex.h index c9ae89f4b6..39fe820e68 100644 --- a/src/rx/FBSD/rx_kmutex.h +++ b/src/rx/FBSD/rx_kmutex.h @@ -18,7 +18,8 @@ #include #include -#ifdef AFS_FBSD50_ENV +#ifdef AFS_FBSD70_ENV +#include #include #else #include @@ -27,36 +28,6 @@ #define RX_ENABLE_LOCKS 1 #define AFS_GLOBAL_RXLOCK_KERNEL -/* - * Condition variables - * - * In Digital Unix (OSF/1), we use something akin to the ancient sleep/wakeup - * mechanism. The condition variable itself plays no role; we just use its - * address as a convenient unique number. - */ -#define CV_INIT(cv,a,b,c) -#define CV_DESTROY(cv) -#define CV_WAIT(cv, lck) { \ - int isGlockOwner = ISAFS_GLOCK(); \ - if (isGlockOwner) AFS_GUNLOCK(); \ - MUTEX_EXIT(lck); \ - tsleep(cv, PSOCK, "afs_rx_cv_wait", 0); \ - if (isGlockOwner) AFS_GLOCK(); \ - MUTEX_ENTER(lck); \ - } - -#define CV_TIMEDWAIT(cv,lck,t) { \ - int isGlockOwner = ISAFS_GLOCK(); \ - if (isGlockOwner) AFS_GUNLOCK(); \ - MUTEX_EXIT(lck); \ - tsleep(cv, PSOCK, "afs_rx_cv_timedwait", t); \ - if (isGlockOwner) AFS_GLOCK(); \ - MUTEX_ENTER(lck); \ - -#define CV_SIGNAL(cv) wakeup_one(cv) -#define CV_BROADCAST(cv) wakeup(cv) - -/* #define osi_rxWakeup(cv) wakeup(cv) */ typedef int afs_kcondvar_t; #define HEAVY_LOCKS @@ -89,7 +60,47 @@ typedef struct { #undef MUTEX_ISMINE #define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == curproc) +#elif defined(AFS_FBSD70_ENV) /* dunno about 6.x */ + +typedef struct mtx afs_kmutex_t; + +#if defined(AFS_FBSD80_ENV) && defined(WITNESS) +#define WITCLEAR_MTX(a) \ + do { memset((a), 0, sizeof(struct mtx)); } while(0); +#else +#define WITCLEAR_MTX(a) {} +#endif + +#define MUTEX_INIT(a,b,c,d) \ + do { \ + WITCLEAR_MTX(a); \ + mtx_init((a), (b), 0 /* type defaults to name */, MTX_DEF | MTX_DUPOK); \ + } while(0); + +#define MUTEX_DESTROY(a) \ + do { \ + mtx_destroy((a)); \ + } while(0); + +#define MUTEX_ENTER(a) \ + do { \ + mtx_lock((a)); \ + } while(0); + +#define MUTEX_TRYENTER(a) \ + ( mtx_trylock((a)) ) + +#define MUTEX_EXIT(a) \ + do { \ + mtx_unlock((a)); \ + } while(0); + +#undef MUTEX_ISMINE +#define MUTEX_ISMINE(a) \ + ( mtx_owned((a)) ) + #elif defined(AFS_FBSD50_ENV) + typedef struct { struct lock lock; struct thread *owner; @@ -133,7 +144,7 @@ typedef struct { #define MUTEX_INIT(a,b,c,d) \ do { \ - lockinit(&(a)->lock,PSOCK, "afs rx mutex", 0, 0); \ + lockinit(&(a)->lock, PSOCK, "afs rx mutex", 0, 0); \ (a)->owner = 0; \ } while(0); #define MUTEX_DESTROY(a) \ @@ -198,4 +209,56 @@ typedef struct { #undef osirx_AssertMine extern void osirx_AssertMine(afs_kmutex_t * lockaddr, char *msg); + +/* + * Condition variables + * + * In Digital Unix (OSF/1), we use something akin to the ancient sleep/wakeup + * mechanism. The condition variable itself plays no role; we just use its + * address as a convenient unique number. + */ +#define CV_INIT(cv,a,b,c) +#define CV_DESTROY(cv) + +#if defined(AFS_FBSD70_ENV) + +#define CV_WAIT(cv, lck) { \ + int isGlockOwner = ISAFS_GLOCK(); \ + if (isGlockOwner) AFS_GUNLOCK(); \ + msleep(cv, lck, PSOCK, "afs_rx_cv_wait", 0); \ + if (isGlockOwner) AFS_GLOCK(); \ + } + +#define CV_TIMEDWAIT(cv,lck,t) { \ + int isGlockOwner = ISAFS_GLOCK(); \ + if (isGlockOwner) AFS_GUNLOCK(); \ + msleep(cv, lck, PSOCK, "afs_rx_cv_timedwait", t); \ + if (isGlockOwner) AFS_GLOCK(); \ + } +#else /* !AFS_FBSD70_ENV */ +#define CV_WAIT(cv, lck) { \ + int isGlockOwner = ISAFS_GLOCK(); \ + if (isGlockOwner) AFS_GUNLOCK(); \ + MUTEX_EXIT(lck); \ + tsleep(cv, PSOCK, "afs_rx_cv_wait", 0); \ + if (isGlockOwner) AFS_GLOCK(); \ + MUTEX_ENTER(lck); \ + } + +#define CV_TIMEDWAIT(cv,lck,t) { \ + int isGlockOwner = ISAFS_GLOCK(); \ + if (isGlockOwner) AFS_GUNLOCK(); \ + MUTEX_EXIT(lck); \ + tsleep(cv, PSOCK, "afs_rx_cv_timedwait", t); \ + if (isGlockOwner) AFS_GLOCK(); \ + MUTEX_ENTER(lck); \ + } +#endif /* AFS_FBSD80_ENV */ + +#define CV_SIGNAL(cv) wakeup_one(cv) +#define CV_BROADCAST(cv) wakeup(cv) + +/* #define osi_rxWakeup(cv) wakeup(cv) */ + + #endif /* _RX_KMUTEX_H_ */ diff --git a/src/rx/FBSD/rx_knet.c b/src/rx/FBSD/rx_knet.c index e70dcb4108..31eea90ac1 100644 --- a/src/rx/FBSD/rx_knet.c +++ b/src/rx/FBSD/rx_knet.c @@ -77,6 +77,8 @@ osi_NetReceive(osi_socket asocket, struct sockaddr_in *addr, return code; } +#define so_is_disconn(so) ((so)->so_state & SS_ISDISCONNECTED) + extern int rxk_ListenerPid; void osi_StopListener(void) @@ -88,15 +90,43 @@ osi_StopListener(void) * soclose() is currently protected by Giant, * but pfind and psignal are MPSAFE. */ - AFS_GUNLOCK(); + int haveGlock = ISAFS_GLOCK(); + if (haveGlock) + AFS_GUNLOCK(); + soshutdown(rx_socket, 2); +#ifndef AFS_FBSD70_ENV soclose(rx_socket); +#endif p = pfind(rxk_ListenerPid); + afs_warn("osi_StopListener: rxk_ListenerPid %lx\n", p); if (p) psignal(p, SIGUSR1); #ifdef AFS_FBSD50_ENV PROC_UNLOCK(p); #endif - AFS_GLOCK(); +#ifdef AFS_FBSD70_ENV + { + /* Avoid destroying socket until osi_NetReceive has + * had a chance to clean up */ + int tries; + struct mtx s_mtx; + + MUTEX_INIT(&s_mtx, "rx_shutdown_mutex", MUTEX_DEFAULT, 0); + MUTEX_ENTER(&s_mtx); + tries = 3; + while ((tries > 0) && (!so_is_disconn(rx_socket))) { + msleep(&osi_StopListener, &s_mtx, PSOCK | PCATCH, + "rx_shutdown_timedwait", 1 * hz); + --tries; + } + if (so_is_disconn(rx_socket)) + soclose(rx_socket); + MUTEX_EXIT(&s_mtx); + MUTEX_DESTROY(&s_mtx); + } +#endif + if (haveGlock) + AFS_GLOCK(); } int diff --git a/src/rx/rx.c b/src/rx/rx.c index dc3817fb19..5d299f7c9b 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -2206,6 +2206,7 @@ rxi_NewCall(register struct rx_connection *conn, register int channel) call->conn = conn; rxi_ResetCall(call, 1); } else { + call = (struct rx_call *)rxi_Alloc(sizeof(struct rx_call)); MUTEX_EXIT(&rx_freeCallQueue_lock); @@ -2314,8 +2315,13 @@ rxi_Alloc(register size_t size) register char *p; rx_MutexAdd1Increment2(rxi_Allocsize, (afs_int32)size, rxi_Alloccnt, rx_stats_mutex); - p = (char *)osi_Alloc(size); +p = (char *) +#if defined(KERNEL) && !defined(UKERNEL) && defined(AFS_FBSD80_ENV) + afs_osi_Alloc_NoSleep(size); +#else + osi_Alloc(size); +#endif if (!p) osi_Panic("rxi_Alloc error"); memset(p, 0, size); @@ -5260,7 +5266,12 @@ rxi_Start(struct rxevent *event, register struct rx_call *call, nXmitPackets = 0; maxXmitPackets = MIN(call->twind, call->cwind); xmitList = (struct rx_packet **) - osi_Alloc(maxXmitPackets * sizeof(struct rx_packet *)); +#if defined(KERNEL) && !defined(UKERNEL) && defined(AFS_FBSD80_ENV) + /* XXXX else we must drop any mtx we hold */ + afs_osi_Alloc_NoSleep(maxXmitPackets * sizeof(struct rx_packet *)); +#else + osi_Alloc(maxXmitPackets * sizeof(struct rx_packet *)); +#endif if (xmitList == NULL) osi_Panic("rxi_Start, failed to allocate xmit list"); for (queue_Scan(&call->tq, p, nxp, rx_packet)) { diff --git a/src/rx/rx_event.c b/src/rx/rx_event.c index 56b90d742a..67f115aae1 100644 --- a/src/rx/rx_event.c +++ b/src/rx/rx_event.c @@ -180,12 +180,20 @@ rxepoch_Allocate(struct clock *when) #if defined(AFS_AIX32_ENV) && defined(KERNEL) ep = (struct rxepoch *)rxi_Alloc(sizeof(struct rxepoch)); queue_Append(&rxepoch_free, &ep[0]), rxepoch_nFree++; +#else +#if defined(KERNEL) && !defined(UKERNEL) && defined(AFS_FBSD80_ENV) + ep = (struct rxepoch *) + afs_osi_Alloc_NoSleep(sizeof(struct rxepoch) * rxepoch_allocUnit); + xsp = xfreemallocs; + xfreemallocs = + (struct xfreelist *)afs_osi_Alloc_NoSleep(sizeof(struct xfreelist)); #else ep = (struct rxepoch *) osi_Alloc(sizeof(struct rxepoch) * rxepoch_allocUnit); xsp = xfreemallocs; xfreemallocs = (struct xfreelist *)osi_Alloc(sizeof(struct xfreelist)); +#endif xfreemallocs->mem = (void *)ep; xfreemallocs->size = sizeof(struct rxepoch) * rxepoch_allocUnit; xfreemallocs->next = xsp; @@ -264,11 +272,20 @@ _rxevent_Post(struct clock *when, struct clock *now, void (*func) (), ev = (struct rxevent *)rxi_Alloc(sizeof(struct rxevent)); queue_Append(&rxevent_free, &ev[0]), rxevent_nFree++; #else + +#if defined(KERNEL) && !defined(UKERNEL) && defined(AFS_FBSD80_ENV) + ev = (struct rxevent *)afs_osi_Alloc_NoSleep(sizeof(struct rxevent) * + rxevent_allocUnit); + xsp = xfreemallocs; + xfreemallocs = + (struct xfreelist *)afs_osi_Alloc_NoSleep(sizeof(struct xfreelist)); +#else ev = (struct rxevent *)osi_Alloc(sizeof(struct rxevent) * rxevent_allocUnit); xsp = xfreemallocs; xfreemallocs = (struct xfreelist *)osi_Alloc(sizeof(struct xfreelist)); +#endif xfreemallocs->mem = (void *)ev; xfreemallocs->size = sizeof(struct rxevent) * rxevent_allocUnit; xfreemallocs->next = xsp; diff --git a/src/rx/rx_multi.c b/src/rx/rx_multi.c index 96fbda809b..b8b3f36209 100644 --- a/src/rx/rx_multi.c +++ b/src/rx/rx_multi.c @@ -48,6 +48,7 @@ multi_Init(struct rx_connection **conns, register int nConns) mh->nextReady = mh->firstNotReady = mh->ready = ready; mh->nReady = 0; mh->nConns = nConns; + #ifdef RX_ENABLE_LOCKS MUTEX_INIT(&mh->lock, "rx_multi_lock", MUTEX_DEFAULT, 0); CV_INIT(&mh->cv, "rx_multi_cv", CV_DEFAULT, 0);