diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c @@ -873,22 +873,39 @@ static int zfsctl_mounted_here(vnode_t **vpp, int flags) { + int error; +#if __FreeBSD_version >= 1400093 + struct vnode *vp; + bool unlocked; +#else struct mount *mp; - int err; +#endif ASSERT_VOP_LOCKED(*vpp, __func__); ASSERT3S((*vpp)->v_type, ==, VDIR); +#if __FreeBSD_version >= 1400093 + KASSERT(vrefcnt(*vpp) > 1, ("unreferenced mountpoint")); + + error = vn_cross_single_mount(*vpp, flags, &unlocked, &vp); + if (__predict_true(error == 0)) + *vpp = vp; + else if (__predict_false(unlocked)) + vn_lock(*vpp, LK_SHARED | LK_RETRY); + + return (error); +#else if ((mp = (*vpp)->v_mountedhere) != NULL) { - err = vfs_busy(mp, 0); - KASSERT(err == 0, ("vfs_busy(mp, 0) failed with %d", err)); + error = vfs_busy(mp, 0); + KASSERT(error == 0, ("vfs_busy(mp, 0) failed with %d", error)); KASSERT(vrefcnt(*vpp) > 1, ("unreferenced mountpoint")); vput(*vpp); - err = VFS_ROOT(mp, flags, vpp); + error = VFS_ROOT(mp, flags, vpp); vfs_unbusy(mp); - return (err); + return (error); } return (EJUSTRETURN); +#endif } typedef struct {