vfs: fix reference counting/locking on LK_UPGRADE error

Factoring out this code unfortunately introduced reference and lock leaks in
case of failure in the lock upgrade path under VV_CROSSLOCK. In terms of
practical use, this impacts unionfs (and nullfs in a corner case).

Fixes:          80bd5ef070 ("vfs: factor out mount point traversal to a dedicated routine")
MFC after:      3 days
MFC to:         stable/14 releng/14.0
Sponsored by:   The FreeBSD Foundation
Reviewed by:	mjg
[mjg: massaged the commit message a little bit]

Differential Revision: https://reviews.freebsd.org/D41731
This commit is contained in:
Olivier Certner 2023-09-22 20:57:20 +00:00 committed by Mateusz Guzik
parent 407e2d7cf1
commit 02cbc029da

View file

@ -905,8 +905,15 @@ vfs_lookup_cross_mount(struct nameidata *ndp)
crosslkflags |= LK_EXCLUSIVE | LK_CANRECURSE;
} else if ((crosslkflags & LK_EXCLUSIVE) != 0) {
error = vn_lock(dp, LK_UPGRADE);
if (error != 0)
if (error != 0) {
MPASS(error == ENOENT);
vrele(dp);
if (dp != ndp->ni_dvp)
vput(ndp->ni_dvp);
else
vrele(ndp->ni_dvp);
break;
}
if (dp->v_mountedhere != mp) {
continue;
}