Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 May 2016 08:02:49 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r300130 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201605180802.u4I82nT5088839@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Wed May 18 08:02:49 2016
New Revision: 300130
URL: https://svnweb.freebsd.org/changeset/base/300130

Log:
  zfsctl_freebsd_root_lookup: gfs_vop_lookup may return a doomed vnode
  
  gfs code is (almsot) completely agnostic of FreeBSD VFS locking, so it
  does not handle doomed but not yet dead vnodes and may return them.
  Check for those vnodes here and retry a lookup.
  Note that ZFS and gfs have additional protections that ensure that a
  parent vnode of the current vnode is never doomed.
  
  The fixed problem is an occasional failure to lookup a 'snapshot' or
  'shares' directories under .zfs.
  
  Note that for the above reason all uses of zfsctl_root_lookup() are
  better be replaced with VOP_LOOKUP.
  
  MFC after:	5 weeks

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

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c	Wed May 18 07:18:11 2016	(r300129)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c	Wed May 18 08:02:49 2016	(r300130)
@@ -603,19 +603,25 @@ zfsctl_freebsd_root_lookup(ap)
 
 	ASSERT(ap->a_cnp->cn_namelen < sizeof(nm));
 	strlcpy(nm, ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen + 1);
+relookup:
 	err = zfsctl_root_lookup(dvp, nm, vpp, NULL, 0, NULL, cr, NULL, NULL, NULL);
 	if (err == 0 && (nm[0] != '.' || nm[1] != '\0')) {
-		if (flags & ISDOTDOT)
+		if (flags & ISDOTDOT) {
 			VOP_UNLOCK(dvp, 0);
-		err = vn_lock(*vpp, lkflags);
-		if (err != 0) {
-			vrele(*vpp);
-			*vpp = NULL;
-		}
-		if (flags & ISDOTDOT)
+			err = vn_lock(*vpp, lkflags);
+			if (err != 0) {
+				vrele(*vpp);
+				*vpp = NULL;
+			}
 			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
+		} else {
+			err = vn_lock(*vpp, LK_EXCLUSIVE);
+			if (err != 0) {
+				VERIFY3S(err, ==, ENOENT);
+				goto relookup;
+			}
+		}
 	}
-
 	return (err);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605180802.u4I82nT5088839>