From owner-svn-src-all@FreeBSD.ORG  Sun Nov  4 14:50:09 2012
Return-Path: <owner-svn-src-all@FreeBSD.ORG>
Delivered-To: svn-src-all@freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
 by hub.freebsd.org (Postfix) with ESMTP id 71CD3F84;
 Sun,  4 Nov 2012 14:50:09 +0000 (UTC) (envelope-from avg@FreeBSD.org)
Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c])
 by mx1.freebsd.org (Postfix) with ESMTP id 59C268FC14;
 Sun,  4 Nov 2012 14:50:09 +0000 (UTC)
Received: from svn.freebsd.org (localhost [127.0.0.1])
 by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id qA4Eo9eb011908;
 Sun, 4 Nov 2012 14:50:09 GMT (envelope-from avg@svn.freebsd.org)
Received: (from avg@localhost)
 by svn.freebsd.org (8.14.4/8.14.4/Submit) id qA4Eo9L1011906;
 Sun, 4 Nov 2012 14:50:09 GMT (envelope-from avg@svn.freebsd.org)
Message-Id: <201211041450.qA4Eo9L1011906@svn.freebsd.org>
From: Andriy Gapon <avg@FreeBSD.org>
Date: Sun, 4 Nov 2012 14:50:09 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-all@freebsd.org,
 svn-src-head@freebsd.org
Subject: svn commit: r242575 -
 head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
X-SVN-Group: head
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-BeenThere: svn-src-all@freebsd.org
X-Mailman-Version: 2.1.14
Precedence: list
List-Id: "SVN commit messages for the entire src tree \(except for &quot;
 user&quot; and &quot; projects&quot; \)" <svn-src-all.freebsd.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/options/svn-src-all>,
 <mailto:svn-src-all-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-all>
List-Post: <mailto:svn-src-all@freebsd.org>
List-Help: <mailto:svn-src-all-request@freebsd.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-all>,
 <mailto:svn-src-all-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Sun, 04 Nov 2012 14:50:09 -0000

Author: avg
Date: Sun Nov  4 14:50:08 2012
New Revision: 242575
URL: http://svn.freebsd.org/changeset/base/242575

Log:
  zfs_dirlook: bailout early if directory is unlinked
  
  Otherwise we could fail with an incorrect error if e.g. parent
  object id is removed too or we can even return a wrong vnode if
  parent object has been already re-used.
  
  Discussed with:	pjd
  Also see:	http://article.gmane.org/gmane.os.freebsd.devel.file-systems/13863
  MFC after:	26 days

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c	Sun Nov  4 14:43:15 2012	(r242574)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c	Sun Nov  4 14:50:08 2012	(r242575)
@@ -374,8 +374,15 @@ zfs_dirlook(znode_t *dzp, char *name, vn
 	znode_t *zp;
 	int error = 0;
 	uint64_t parent;
+	int unlinked;
 
 	if (name[0] == 0 || (name[0] == '.' && name[1] == 0)) {
+		mutex_enter(&dzp->z_lock);
+		unlinked = dzp->z_unlinked;
+		mutex_exit(&dzp->z_lock);
+		if (unlinked)
+			return (ENOENT);
+
 		*vpp = ZTOV(dzp);
 		VN_HOLD(*vpp);
 	} else if (name[0] == '.' && name[1] == '.' && name[2] == 0) {
@@ -394,6 +401,13 @@ zfs_dirlook(znode_t *dzp, char *name, vn
 			    NULL, NULL, NULL);
 			return (error);
 		}
+
+		mutex_enter(&dzp->z_lock);
+		unlinked = dzp->z_unlinked;
+		mutex_exit(&dzp->z_lock);
+		if (unlinked)
+			return (ENOENT);
+
 		rw_enter(&dzp->z_parent_lock, RW_READER);
 		error = zfs_zget(zfsvfs, parent, &zp);
 		if (error == 0)