git: cb1ee0c32144 - stable/14 - vfs_lookup_cross_mount(): fix missing LK_CANRECURSE
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 21 Sep 2026 05:11:15 UTC
The branch stable/14 has been updated by jah:
URL: https://cgit.FreeBSD.org/src/commit/?id=cb1ee0c3214405331bb8085d3be910d4f560edbc
commit cb1ee0c3214405331bb8085d3be910d4f560edbc
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-21 05:10:47 +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
Differential Revision: https://reviews.freebsd.org/D59494
(cherry picked from commit f57ce26f2572efb8adc825ad4efc0e0743a9112f)
---
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 1d303fecf493..c0322d59693e 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -941,16 +941,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);