git: 23152cae2f7d - stable/15 - vfs_lookup_cross_mount(): fix missing LK_CANRECURSE
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 21 Sep 2026 05:10:29 UTC
The branch stable/15 has been updated by jah:
URL: https://cgit.FreeBSD.org/src/commit/?id=23152cae2f7df9a4291aa2cc8705600bbd78c57e
commit 23152cae2f7df9a4291aa2cc8705600bbd78c57e
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:09:22 +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 0550a4fc0d4d..6f06fc8268fc 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -979,16 +979,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);