aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Certner <olce.freebsd@certner.fr>2023-09-22 20:57:20 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2023-09-24 10:44:11 +0000
commitc76dfb929e70c80a2d0280a1371c07738d910c11 (patch)
treea64abaf17e0814b77fc72ed0667dd50398ea4b68
parentbb438c08b86a32f13da16b2e7801f2cbd45bc5c1 (diff)
downloadsrc-c76dfb929e70c80a2d0280a1371c07738d910c11.tar.gz
src-c76dfb929e70c80a2d0280a1371c07738d910c11.zip
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: 80bd5ef07025 ("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 (cherry picked from commit 02cbc029dac936b4ddbc38cef969c4b30c9a7d1f)
-rw-r--r--sys/kern/vfs_lookup.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index 151253ffa0f5..d75351c34314 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -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;
}