From owner-svn-src-all@FreeBSD.ORG Thu Sep 24 15:49:15 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7AB861065697; Thu, 24 Sep 2009 15:49:15 +0000 (UTC) (envelope-from pjd@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 587BF8FC19; Thu, 24 Sep 2009 15:49:15 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n8OFnF90000885; Thu, 24 Sep 2009 15:49:15 GMT (envelope-from pjd@svn.freebsd.org) Received: (from pjd@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n8OFnF3L000883; Thu, 24 Sep 2009 15:49:15 GMT (envelope-from pjd@svn.freebsd.org) Message-Id: <200909241549.n8OFnF3L000883@svn.freebsd.org> From: Pawel Jakub Dawidek Date: Thu, 24 Sep 2009 15:49:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r197458 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 Sep 2009 15:49:15 -0000 Author: pjd Date: Thu Sep 24 15:49:15 2009 New Revision: 197458 URL: http://svn.freebsd.org/changeset/base/197458 Log: Close race in zfs_zget(). We have to increase usecount first and then check for VI_DOOMED flag. Before this change vnode could be reclaimed between checking for the flag and increasing usecount. MFC after: 3 days 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 Thu Sep 24 15:34:18 2009 (r197457) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Thu Sep 24 15:49:15 2009 (r197458) @@ -890,17 +890,25 @@ again: if (zp->z_unlinked) { err = ENOENT; } else { - if ((vp = ZTOV(zp)) != NULL) { - VI_LOCK(vp); + int dying = 0; + + vp = ZTOV(zp); + if (vp == NULL) + dying = 1; + else { + VN_HOLD(vp); if ((vp->v_iflag & VI_DOOMED) != 0) { - VI_UNLOCK(vp); - vp = NULL; - } else - VI_UNLOCK(vp); + dying = 1; + /* + * Don't VN_RELE() vnode here, because + * it can call vn_lock() which creates + * LOR between vnode lock and znode + * lock. We will VN_RELE() the vnode + * after droping znode lock. + */ + } } - if (vp != NULL) - VN_HOLD(vp); - else { + if (dying) { if (first) { ZFS_LOG(1, "dying znode detected (zp=%p)", zp); first = 0; @@ -912,6 +920,8 @@ again: dmu_buf_rele(db, NULL); mutex_exit(&zp->z_lock); ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); + if (vp != NULL) + VN_RELE(vp); tsleep(zp, 0, "zcollide", 1); goto again; }