From a3da8d3cae6ff49fc79f222c1874ee28c23a01bf Mon Sep 17 00:00:00 2001 From: emaste Date: Wed, 19 Dec 2018 18:05:50 +0000 Subject: [PATCH] MFS11 r341828: Resolve a hang in ZFS during vnode reclaimation This is caused by a deadlock between zil_commit() and zfs_zget() Add a way for zfs_zget() to break out of the retry loop in the common case PR: 229614, 231117 Submitted by: allanjude Approved by: so Security: FreeBSD-EN-18:18.zfs Sponsored by: Klara Systems, The FreeBSD Foundation --- .../opensolaris/uts/common/fs/zfs/zfs_znode.c | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c index 58c3807f6ae..9d1a723a0cc 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c @@ -1155,15 +1155,27 @@ zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) */ ASSERT3P(zp, !=, NULL); ASSERT3U(zp->z_id, ==, obj_num); - *zpp = zp; - vp = ZTOV(zp); - - /* Don't let the vnode disappear after ZFS_OBJ_HOLD_EXIT. */ - VN_HOLD(vp); + if (zp->z_unlinked) { + err = SET_ERROR(ENOENT); + } else { + vp = ZTOV(zp); + /* + * Don't let the vnode disappear after + * ZFS_OBJ_HOLD_EXIT. + */ + VN_HOLD(vp); + *zpp = zp; + err = 0; + } sa_buf_rele(db, NULL); ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + if (err) { + getnewvnode_drop_reserve(); + return (err); + } + locked = VOP_ISLOCKED(vp); VI_LOCK(vp); if ((vp->v_iflag & VI_DOOMED) != 0 && @@ -1196,7 +1208,7 @@ zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) } VI_UNLOCK(vp); getnewvnode_drop_reserve(); - return (0); + return (err); } /* -- 2.45.0