From owner-svn-src-head@freebsd.org Wed Jan 31 14:44:52 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A97EEECF2C4; Wed, 31 Jan 2018 14:44:52 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 5631B86C5E; Wed, 31 Jan 2018 14:44:52 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 32935274B0; Wed, 31 Jan 2018 14:44:52 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w0VEiqI4036128; Wed, 31 Jan 2018 14:44:52 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w0VEiqTV036127; Wed, 31 Jan 2018 14:44:52 GMT (envelope-from avg@FreeBSD.org) Message-Id: <201801311444.w0VEiqTV036127@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Wed, 31 Jan 2018 14:44:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r328626 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: head X-SVN-Commit-Author: avg X-SVN-Commit-Paths: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Commit-Revision: 328626 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 31 Jan 2018 14:44:52 -0000 Author: avg Date: Wed Jan 31 14:44:51 2018 New Revision: 328626 URL: https://svnweb.freebsd.org/changeset/base/328626 Log: zfs_rezget: drop cached pages before doing anything else We did that in the case of success to prevent the use of stale cached data, but it makes even less sense to keep the cached data when we fail. Ideally, we should call vgone() on the vnode in the case of zfs_rezget failure, but the current lock order prevents us from doing that. The change also rearranges the order of unlinked check and the size change check. While there, add missing SET_ERROR in one of the error paths. MFC after: 2 weeks Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Wed Jan 31 14:36:27 2018 (r328625) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Wed Jan 31 14:44:51 2018 (r328626) @@ -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);