svn commit: r206667 -
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Pawel Jakub Dawidek
pjd at FreeBSD.org
Thu Apr 15 16:40:55 UTC 2010
Author: pjd
Date: Thu Apr 15 16:40:54 2010
New Revision: 206667
URL: http://svn.freebsd.org/changeset/base/206667
Log:
Fix 3-way deadlock that can happen because of ZFS and vnode lock
order reversal.
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)
Submitted by: Attila Nagy <bra at fsn.hu>
MFC after: 3 days
Modified:
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Thu Apr 15 16:35:34 2010 (r206666)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Thu Apr 15 16:40:54 2010 (r206667)
@@ -868,13 +868,15 @@ zfs_root(vfs_t *vfsp, int flags, vnode_t
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 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int fla
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 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vno
} else {
VN_HOLD(*vpp);
}
- vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
ZFS_EXIT(zfsvfs);
+ vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
return (0);
}
@@ -1259,10 +1261,11 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vno
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);
}
Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Thu Apr 15 16:35:34 2010 (r206666)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Thu Apr 15 16:40:54 2010 (r206667)
@@ -1209,15 +1209,17 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode
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 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode
}
#endif
- ZFS_EXIT(zfsvfs);
-
return (error);
}
More information about the svn-src-all
mailing list