git: 7fd37611b92b - main - null_vptocnp(): busy nullfs mp instead of refing it
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 14 Jun 2022 07:33:22 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=7fd37611b92b5f365f33435bb725b335c2f10ba8
commit 7fd37611b92b5f365f33435bb725b335c2f10ba8
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-06-10 11:35:45 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-06-14 07:32:45 +0000
null_vptocnp(): busy nullfs mp instead of refing it
null_nodeget() needs a valid mount point data, otherwise we might
race and dereference NULL.
Using MBF_NOWAIT makes non-forced unmount non-transparent for
vn_fullpath() over nullfs, but we make no guarantee that fullpath
calculation succeeds anyway.
Reported and tested by: pho
Reviewed by: jah
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D35477
---
sys/fs/nullfs/null_vnops.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
index e3a320a22bfa..bb18bc8ee55f 100644
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -989,9 +989,11 @@ null_vptocnp(struct vop_vptocnp_args *ap)
locked = VOP_ISLOCKED(vp);
lvp = NULLVPTOLOWERVP(vp);
- vhold(lvp);
mp = vp->v_mount;
- vfs_ref(mp);
+ error = vfs_busy(mp, MBF_NOWAIT);
+ if (error != 0)
+ return (error);
+ vhold(lvp);
VOP_UNLOCK(vp); /* vp is held by vn_vptocnp_locked that called us */
ldvp = lvp;
vref(lvp);
@@ -999,7 +1001,7 @@ null_vptocnp(struct vop_vptocnp_args *ap)
vdrop(lvp);
if (error != 0) {
vn_lock(vp, locked | LK_RETRY);
- vfs_rel(mp);
+ vfs_unbusy(mp);
return (ENOENT);
}
@@ -1007,7 +1009,7 @@ null_vptocnp(struct vop_vptocnp_args *ap)
if (error != 0) {
vrele(ldvp);
vn_lock(vp, locked | LK_RETRY);
- vfs_rel(mp);
+ vfs_unbusy(mp);
return (ENOENT);
}
error = null_nodeget(mp, ldvp, dvp);
@@ -1018,7 +1020,7 @@ null_vptocnp(struct vop_vptocnp_args *ap)
VOP_UNLOCK(*dvp); /* keep reference on *dvp */
}
vn_lock(vp, locked | LK_RETRY);
- vfs_rel(mp);
+ vfs_unbusy(mp);
return (error);
}