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
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
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.
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);
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);
{
struct vattr tvattr;
struct vnode *vp;
- register afs_int32 code;
+ register afs_int32 code, glocked;
AFS_STATCNT(osi_Truncate);
MObtainWriteLock(&afs_xosi, 321);
* 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
#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;
}
#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
#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)
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;
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;
}
{
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);
}
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);
}
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)
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;
}
* 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);
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 */
#include <afsconfig.h>
#include "afs/param.h"
+#ifdef AFS_FBSD70_ENV
+#include <sys/param.h>
+#include <sys/vnode.h>
+ void
+ vgonel(struct vnode *vp, struct thread *td);
+#endif
RCSID
("$Header$");
#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
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;
*/
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);
{
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.
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,
.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 */
{&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 =
#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
#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;
* 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);
/* 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;
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;
*/
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
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;
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);
}
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();
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
}
}
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;
}
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;
}
afs_InitFakeStat(&fakestate);
AFS_DISCON_LOCK();
-
- /*printf("Looking up %s\n", aname);*/
if ((code = afs_InitReq(&treq, acred)))
goto done;
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;
/* 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 {
ReleaseWriteLock(&tvc->lock);
if (code) {
+#ifndef AFS_FBSD80_ENV
afs_PutVCache(tvc);
+#endif
if (tvolp)
afs_PutVolume(tvolp, WRITE_LOCK);
goto done;
} 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;
afs_PutVolume(tvolp, WRITE_LOCK);
}
} else {
+#ifndef AFS_FBSD80_ENV
afs_PutVCache(tvc);
+#endif
code = ENOENT;
if (tvolp)
afs_PutVolume(tvolp, WRITE_LOCK);
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);
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);
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 */
* 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 */
break;
}
} /* big while loop */
+
+#if defined(AFS_FBSD80_ENV) && !defined(UKERNEL)
+ VFS_UNLOCK_GIANT(vfslocked);
+#endif
+
return;
} /*afs_GetDownD */
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)
#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"
afs_stats_cmperf.SmallBlocksActive);
}
}
-#endif
+
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
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
#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)
{
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);
ReleaseReadLock(&afs_xdnlc);
ReleaseReadLock(&afs_xvcache);
osi_dnlc_purge();
+ ma_critical_exit();
return (0);
}
}
ReleaseReadLock(&afs_xvcache);
dnlcstats.misses++;
osi_dnlc_remove(adp, aname, tvc);
+ ma_critical_exit();
return 0;
}
#ifdef AFS_OSF_ENV
ReleaseReadLock(&afs_xvcache);
dnlcstats.misses++;
osi_dnlc_remove(adp, aname, tvc);
+ ma_critical_exit();
return 0;
}
if (vnode_ref(tvp)) {
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);
#endif
}
+ ma_critical_exit();
return tvc;
}
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);
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)
#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
--- /dev/null
+#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 <sys/param.h>
+#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 <afs/afs_sysnames.h>
+
+#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 <afs/afs_sysnames.h>
+
+#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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <limits.h>
+
+#endif /* !defined(UKERNEL) */
+
+/* general user-space compiles */
+
+#if defined(UKERNEL) || !defined(KERNEL)
+#define STDLIB_HAS_MALLOC_PROTOS 1
+#endif
+
+#endif /* AFS_PARAM_H */
-ln -fs ${KSRC}/@HOST_CPU@/include machine
-ln -fs ${KSRC}/netinet netinet
-ln -fs ${KSRC}/nfs nfs
+<all -i386_fbsd_80>
-ln -fs /usr/include/rpc rpc
+<i386_fbsd_80>
+ -ln -fs ${KSRC}/rpc rpc
+<all>
-ln -fs ${KSRC}/sys sys
-ln -fs ${KSRC}/ufs/ufs ufs
-ln -fs ${KSRC}/sys h
TEST_CFLAGS=-D_REENTRANT -DAFS_PTHREAD_ENV -DAFS_FBSD40_ENV
TEST_LDFLAGS=
-<all -i386_fbsd_62 -i386_fbsd_70>
+<all -i386_fbsd_62 -i386_fbsd_70 -i386_fbsd_80>
TEST_LIBS=-lc_r
-<i386_fbsd_62 -i386_fbsd_70>
+<i386_fbsd_62 i386_fbsd_70 i386_fbsd_80>
TEST_LIBS=-lpthread
<all>
#include <sys/systm.h>
#include <sys/proc.h>
-#ifdef AFS_FBSD50_ENV
+#ifdef AFS_FBSD70_ENV
+#include <sys/lock.h>
#include <sys/lockmgr.h>
#else
#include <sys/lock.h>
#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
#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;
#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) \
#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_ */
return code;
}
+#define so_is_disconn(so) ((so)->so_state & SS_ISDISCONNECTED)
+
extern int rxk_ListenerPid;
void
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
call->conn = conn;
rxi_ResetCall(call, 1);
} else {
+
call = (struct rx_call *)rxi_Alloc(sizeof(struct rx_call));
MUTEX_EXIT(&rx_freeCallQueue_lock);
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);
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)) {
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;
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;
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);