svn commit: r330060 - stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Andriy Gapon
avg at FreeBSD.org
Tue Feb 27 14:29:21 UTC 2018
Author: avg
Date: Tue Feb 27 14:29:20 2018
New Revision: 330060
URL: https://svnweb.freebsd.org/changeset/base/330060
Log:
MFC r328626: zfs_rezget: drop cached pages before doing anything else
Modified:
stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
==============================================================================
--- stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Tue Feb 27 14:23:43 2018 (r330059)
+++ stable/11/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Tue Feb 27 14:29:20 2018 (r330060)
@@ -1250,6 +1250,16 @@ zfs_rezget(znode_t *zp)
int count = 0;
uint64_t gen;
+ /*
+ * Remove cached pages before reloading the znode, so that they are not
+ * lingering after we run into any error. Ideally, we should vgone()
+ * the vnode in case of error, but currently we cannot do that
+ * because of the LOR between the vnode lock and z_teardown_lock.
+ * So, instead, we have to "doom" the znode in the illumos style.
+ */
+ vp = ZTOV(zp);
+ vn_pages_remove(vp, 0, 0);
+
ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num);
mutex_enter(&zp->z_acl_lock);
@@ -1329,18 +1339,12 @@ zfs_rezget(znode_t *zp)
* (e.g. via a look-up). The old vnode and znode will be
* recycled when the last vnode reference is dropped.
*/
- vp = ZTOV(zp);
if (vp->v_type != IFTOVT((mode_t)zp->z_mode)) {
zfs_znode_dmu_fini(zp);
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
- return (EIO);
+ return (SET_ERROR(EIO));
}
- zp->z_blksz = doi.doi_data_block_size;
- vn_pages_remove(vp, 0, 0);
- if (zp->z_size != size)
- vnode_pager_setsize(vp, zp->z_size);
-
/*
* If the file has zero links, then it has been unlinked on the send
* side and it must be in the received unlinked set.
@@ -1351,8 +1355,15 @@ zfs_rezget(znode_t *zp)
* when the unlinked set gets processed.
*/
zp->z_unlinked = (zp->z_links == 0);
- if (zp->z_unlinked)
+ if (zp->z_unlinked) {
zfs_znode_dmu_fini(zp);
+ ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
+ return (0);
+ }
+
+ zp->z_blksz = doi.doi_data_block_size;
+ if (zp->z_size != size)
+ vnode_pager_setsize(vp, zp->z_size);
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
More information about the svn-src-stable
mailing list