summaryrefslogtreecommitdiff
path: root/sys/kern/vfs_vops.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/vfs_vops.c')
-rw-r--r--sys/kern/vfs_vops.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/sys/kern/vfs_vops.c b/sys/kern/vfs_vops.c
index 9c39ab07705..e606c0b8af7 100644
--- a/sys/kern/vfs_vops.c
+++ b/sys/kern/vfs_vops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_vops.c,v 1.21 2019/05/03 14:24:13 visa Exp $ */
+/* $OpenBSD: vfs_vops.c,v 1.22 2019/08/26 18:56:29 anton Exp $ */
/*
* Copyright (c) 2010 Thordur I. Bjornsson <thib@openbsd.org>
*
@@ -46,6 +46,7 @@
#include <sys/vnode.h>
#include <sys/unistd.h>
#include <sys/systm.h>
+#include <sys/lock.h> /* LK_DRAIN */
#ifdef VFSLCKDEBUG
#include <sys/systm.h> /* for panic() */
@@ -599,6 +600,17 @@ VOP_LOCK(struct vnode *vp, int flags)
if (vp->v_op->vop_lock == NULL)
return (EOPNOTSUPP);
+ if ((flags & LK_DRAIN) && vp->v_lockcount > 0) {
+ /*
+ * Ensure that any thread currently waiting on the same lock has
+ * observed that the vnode is about to be exclusively locked
+ * before continuing.
+ */
+ KASSERT(vp->v_flag & VXLOCK);
+ tsleep(&vp->v_lockcount, PINOD, "vop_lock", 0);
+ KASSERT(vp->v_lockcount == 0);
+ }
+
return ((vp->v_op->vop_lock)(&a));
}