aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Certner <olce.freebsd@certner.fr>2023-07-09 17:12:52 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2023-07-21 09:21:38 +0000
commit2238fb423031ff7cccdf733a89f9d26198e39af0 (patch)
tree9fcad87f1f2b019dd06a922cceab723af895dc40
parent3b0dacf6fd13cf8688402561192899507f46c276 (diff)
downloadsrc-2238fb423031ff7cccdf733a89f9d26198e39af0.tar.gz
src-2238fb423031ff7cccdf733a89f9d26198e39af0.zip
vn_lock_pair(): Support passing LK_NODDLKTREAT
(cherry picked from commit f58378393fb00f1683bc15f1ae7cbb83e047b9fb)
-rw-r--r--sys/kern/vfs_vnops.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index e314739fa0ad..628e3aecc864 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -3878,6 +3878,9 @@ vn_lock_pair_pause(const char *wmesg)
* Both vnodes could be unlocked temporary (and reclaimed).
*
* If requesting shared locking, locked vnode lock must not be recursed.
+ *
+ * Only one of LK_SHARED and LK_EXCLUSIVE must be specified.
+ * LK_NODDLKTREAT can be optionally passed.
*/
void
vn_lock_pair(struct vnode *vp1, bool vp1_locked, int lkflags1,
@@ -3885,19 +3888,21 @@ vn_lock_pair(struct vnode *vp1, bool vp1_locked, int lkflags1,
{
int error;
- MPASS(lkflags1 == LK_SHARED || lkflags1 == LK_EXCLUSIVE);
- MPASS(lkflags2 == LK_SHARED || lkflags2 == LK_EXCLUSIVE);
+ MPASS((lkflags1 & LK_SHARED) != 0 ^ (lkflags1 & LK_EXCLUSIVE) != 0);
+ MPASS((lkflags1 & ~(LK_SHARED | LK_EXCLUSIVE | LK_NODDLKTREAT)) == 0);
+ MPASS((lkflags2 & LK_SHARED) != 0 ^ (lkflags2 & LK_EXCLUSIVE) != 0);
+ MPASS((lkflags2 & ~(LK_SHARED | LK_EXCLUSIVE | LK_NODDLKTREAT)) == 0);
if (vp1 == NULL && vp2 == NULL)
return;
if (vp1 != NULL) {
- if (lkflags1 == LK_SHARED &&
+ if ((lkflags1 & LK_SHARED) != 0 &&
(vp1->v_vnlock->lock_object.lo_flags & LK_NOSHARE) != 0)
- lkflags1 = LK_EXCLUSIVE;
+ lkflags1 = (lkflags1 & ~LK_SHARED) | LK_EXCLUSIVE;
if (vp1_locked && VOP_ISLOCKED(vp1) != LK_EXCLUSIVE) {
ASSERT_VOP_LOCKED(vp1, "vp1");
- if (lkflags1 == LK_EXCLUSIVE) {
+ if ((lkflags1 & LK_EXCLUSIVE) != 0) {
VOP_UNLOCK(vp1);
ASSERT_VOP_UNLOCKED(vp1,
"vp1 shared recursed");
@@ -3910,12 +3915,12 @@ vn_lock_pair(struct vnode *vp1, bool vp1_locked, int lkflags1,
}
if (vp2 != NULL) {
- if (lkflags2 == LK_SHARED &&
+ if ((lkflags2 & LK_SHARED) != 0 &&
(vp2->v_vnlock->lock_object.lo_flags & LK_NOSHARE) != 0)
- lkflags2 = LK_EXCLUSIVE;
+ lkflags2 = (lkflags2 & ~LK_SHARED) | LK_EXCLUSIVE;
if (vp2_locked && VOP_ISLOCKED(vp2) != LK_EXCLUSIVE) {
ASSERT_VOP_LOCKED(vp2, "vp2");
- if (lkflags2 == LK_EXCLUSIVE) {
+ if ((lkflags2 & LK_EXCLUSIVE) != 0) {
VOP_UNLOCK(vp2);
ASSERT_VOP_UNLOCKED(vp2,
"vp2 shared recursed");