git: f57ce26f2572 - main - vfs_lookup_cross_mount(): fix missing LK_CANRECURSE
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 13 Sep 2026 03:19:33 UTC
The branch main has been updated by jah:
URL: https://cgit.FreeBSD.org/src/commit/?id=f57ce26f2572efb8adc825ad4efc0e0743a9112f
commit f57ce26f2572efb8adc825ad4efc0e0743a9112f
Author: Jason A. Harmening <jah@FreeBSD.org>
AuthorDate: 2026-09-07 17:36:20 +0000
Commit: Jason A. Harmening <jah@FreeBSD.org>
CommitDate: 2026-09-13 03:19:03 +0000
vfs_lookup_cross_mount(): fix missing LK_CANRECURSE
This was a rather dumb miss on my part in commit 42442d7a6e.
LK_CANRECURSE is clearly needed in any case in which the covered vnode
is held exclusive across the call to VFS_ROOT(), regardless of whether
it was initially held exclusive or upgraded. The commit message for
that change also noted that unionfs lookup only worked without
LK_CANRECURSE due to a coincidence of the then-current unionfs
implementation. As it happens, said coincidence was recently removed
in commit b952606b4f ("unionfs_lock(): eliminate LK_CANRECURSE special-
case").
PR: 298201
Reported by: olivier
Fixes: 42442d7a6e "Generalize the VV_CROSSLOCK logic in
vfs_lookup"
Reviewed by: kib, markj, pho
Tested by: pho
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D59494
---
sys/kern/vfs_lookup.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index 71d4d3f75721..34e9bb47b532 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -983,16 +983,20 @@ vfs_lookup_cross_mount(struct nameidata *ndp)
* We are going to be holding the vnode lock, which
* in this case is shared by the root vnode of the
* filesystem mounted at mp, across the call to
- * VFS_ROOT(). Make the situation clear to the
+ * VFS_ROOT(). Make the situation clear to that
* filesystem by passing LK_CANRECURSE if the
- * lock is held exclusive, or by clearinng
- * LK_NODDLKTREAT to allow recursion on the shared
- * lock in the presence of an exclusive waiter.
+ * lock is held exclusive, upgrading the lock (and
+ * passing LK_CANRECURSE) if the lock is held shared
+ * but mp requires an exclusive lock for lookup,
+ * or clearing LK_NODDLKTREAT to allow recursion on
+ * the shared lock in the presence of an exclusive
+ * waiter.
*/
if (VOP_ISLOCKED(dp) == LK_EXCLUSIVE) {
crosslkflags &= ~LK_SHARED;
crosslkflags |= LK_EXCLUSIVE | LK_CANRECURSE;
} else if ((crosslkflags & LK_EXCLUSIVE) != 0) {
+ crosslkflags |= LK_CANRECURSE;
error = vn_lock(dp, LK_UPGRADE);
if (error != 0) {
MPASS(error == ENOENT);