diff options
author | emaste <emaste@FreeBSD.org> | 2018-12-19 18:05:50 +0000 |
---|---|---|
committer | emaste <emaste@FreeBSD.org> | 2018-12-19 18:05:50 +0000 |
commit | a3da8d3cae6ff49fc79f222c1874ee28c23a01bf (patch) | |
tree | fa96d63bf5b0127c766ec620f77d47ade3b555d4 | |
parent | 55d91311564a9ef552650b09731e5daf20ef1af5 (diff) | |
download | FreeBSD-src-a3da8d3cae6ff49fc79f222c1874ee28c23a01bf.zip FreeBSD-src-a3da8d3cae6ff49fc79f222c1874ee28c23a01bf.tar.gz |
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
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c | 24 |
1 files 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 58c3807..9d1a723 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 @@ again: */ 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 @@ again: } VI_UNLOCK(vp); getnewvnode_drop_reserve(); - return (0); + return (err); } /* |