diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -5736,6 +5736,7 @@ } } +#ifdef INVARIANTS #ifdef DEBUG_VFS_LOCKS int vfs_badlock_ddb = 1; /* Drop into debugger on violation. */ SYSCTL_INT(_debug, OID_AUTO, vfs_badlock_ddb, CTLFLAG_RW, &vfs_badlock_ddb, 0, @@ -5762,7 +5763,6 @@ static void vfs_badlock(const char *msg, const char *str, struct vnode *vp) { - #ifdef KDB if (vfs_badlock_backtrace) kdb_backtrace(); @@ -5774,64 +5774,97 @@ if (vfs_badlock_ddb) kdb_enter(KDB_WHY_VFSLOCK, "lock violation"); } +#endif /* DEBUG_VFS_LOCKS */ void assert_vi_locked(struct vnode *vp, const char *str) { - +#ifdef DEBUG_VFS_LOCKS if (vfs_badlock_mutex && !mtx_owned(VI_MTX(vp))) vfs_badlock("interlock is not locked but should be", str, vp); +#else + (void)str; + mtx_assert(VI_MTX(vp), MA_OWNED); +#endif } void assert_vi_unlocked(struct vnode *vp, const char *str) { - +#ifdef DEBUG_VFS_LOCKS if (vfs_badlock_mutex && mtx_owned(VI_MTX(vp))) vfs_badlock("interlock is locked but should not be", str, vp); +#else + (void)str; + mtx_assert(VI_MTX(vp), MA_NOTOWNED); +#endif } void assert_vop_locked(struct vnode *vp, const char *str) { + bool locked; + if (KERNEL_PANICKED() || vp == NULL) return; #ifdef WITNESS - if ((vp->v_irflag & VIRF_CROSSMP) == 0 && - witness_is_owned(&vp->v_vnlock->lock_object) == -1) + locked = !((vp->v_irflag & VIRF_CROSSMP) == 0 && + witness_is_owned(&vp->v_vnlock->lock_object) == -1); #else - int locked = VOP_ISLOCKED(vp); - if (locked == 0 || locked == LK_EXCLOTHER) + int state = VOP_ISLOCKED(vp); + locked = state != 0 && state != LK_EXCLOTHER; #endif +#ifdef DEBUG_VFS_LOCKS + if (!locked) vfs_badlock("is not locked but should be", str, vp); +#else + KASSERT(locked, + ("%s: vnode %p is not locked but should be", str, vp)); +#endif } void assert_vop_unlocked(struct vnode *vp, const char *str) { + bool locked; + if (KERNEL_PANICKED() || vp == NULL) return; #ifdef WITNESS - if ((vp->v_irflag & VIRF_CROSSMP) == 0 && - witness_is_owned(&vp->v_vnlock->lock_object) == 1) + locked = (vp->v_irflag & VIRF_CROSSMP) == 0 && + witness_is_owned(&vp->v_vnlock->lock_object) == 1; #else - if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE) + locked = VOP_ISLOCKED(vp) == LK_EXCLUSIVE; #endif +#ifdef DEBUG_VFS_LOCKS + if (locked) vfs_badlock("is locked but should not be", str, vp); +#else + KASSERT(!locked, + ("%s: vnode %p is locked but should not be", str, vp)); +#endif } void assert_vop_elocked(struct vnode *vp, const char *str) { + bool locked; + if (KERNEL_PANICKED() || vp == NULL) return; - if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) + locked = VOP_ISLOCKED(vp) == LK_EXCLUSIVE; +#ifdef DEBUG_VFS_LOCKS + if (!locked) vfs_badlock("is not exclusive locked but should be", str, vp); +#else + KASSERT(locked, + ("%s: vnode %p is not exclusive locked but should be", str, vp)); +#endif } -#endif /* DEBUG_VFS_LOCKS */ +#endif /* INVARIANTS */ void vop_rename_fail(struct vop_rename_args *ap) diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -538,7 +538,7 @@ #define VOPARG_OFFSETTO(s_type, s_offset, struct_p) \ ((s_type)(((char*)(struct_p)) + (s_offset))) -#ifdef DEBUG_VFS_LOCKS +#ifdef INVARIANTS /* * Support code to aid in debugging VFS locking problems. Not totally * reliable since if the thread sleeps between changing the lock