thread0 (vfs_fhtovp) thread1 (vop_getattr) thread2 (zfs_recv) -------------------- --------------------- ------------------ vn_lock rrw_enter_read rrw_enter_write (hangs) rrw_enter_read (hangs) vn_lock (hangs) Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c (wersja 204364) +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c (kopia robocza) @@ -1209,15 +1209,17 @@ ltype = VOP_ISLOCKED(dvp); VOP_UNLOCK(dvp, 0); } + ZFS_EXIT(zfsvfs); error = vn_lock(*vpp, cnp->cn_lkflags); if (cnp->cn_flags & ISDOTDOT) vn_lock(dvp, ltype | LK_RETRY); if (error != 0) { VN_RELE(*vpp); *vpp = NULL; - ZFS_EXIT(zfsvfs); return (error); } + } else { + ZFS_EXIT(zfsvfs); } #ifdef FREEBSD_NAMECACHE @@ -1237,8 +1239,6 @@ } #endif - ZFS_EXIT(zfsvfs); - return (error); } Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c (wersja 204364) +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c (kopia robocza) @@ -868,13 +868,15 @@ ZFS_ENTER_NOERROR(zfsvfs); error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp); + + ZFS_EXIT(zfsvfs); + if (error == 0) { *vpp = ZTOV(rootzp); error = vn_lock(*vpp, flags); (*vpp)->v_vflag |= VV_ROOT; } - ZFS_EXIT(zfsvfs); return (error); } @@ -1143,13 +1145,13 @@ VN_RELE(ZTOV(zp)); err = EINVAL; } + ZFS_EXIT(zfsvfs); if (err != 0) *vpp = NULL; else { *vpp = ZTOV(zp); vn_lock(*vpp, flags); } - ZFS_EXIT(zfsvfs); return (err); } @@ -1237,8 +1239,8 @@ } else { VN_HOLD(*vpp); } + ZFS_EXIT(zfsvfs); vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY); - ZFS_EXIT(zfsvfs); return (0); } @@ -1259,10 +1261,11 @@ return (EINVAL); } + ZFS_EXIT(zfsvfs); + *vpp = ZTOV(zp); vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY); vnode_create_vobject(*vpp, zp->z_phys->zp_size, curthread); - ZFS_EXIT(zfsvfs); return (0); }