svn commit: r303791 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs

Andriy Gapon avg at FreeBSD.org
Sat Aug 6 11:02:09 UTC 2016


Author: avg
Date: Sat Aug  6 11:02:07 2016
New Revision: 303791
URL: https://svnweb.freebsd.org/changeset/base/303791

Log:
  fix .zfs-related cases in zfs_lookup that were broken by r303763
  
  The problem is that the special .zfs nodes are not represented by
  znodes but by special gfs-based nodes.
  r303763 changed interface of zfs_dirlook such that started operating on
  znodes rather than on vnodes and, thus, the function became unsuitable
  for handling .zfs entities.
  The solution is to move the handling of the special cases to zfs_lookup,
  the only consumer of zfs_dirlook.
  I already had this solution applied in D7421, but for different reasons.
  
  Reported by:	asomers
  MFC after:	3 days
  X-MFC with:	r303763

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.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	Sat Aug  6 08:23:36 2016	(r303790)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c	Sat Aug  6 11:02:07 2016	(r303791)
@@ -173,7 +173,6 @@ zfs_dd_lookup(znode_t *dzp, znode_t **zp
 {
 	zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
 	znode_t *zp;
-	vnode_t *vp;
 	uint64_t parent;
 	int error;
 
@@ -187,19 +186,7 @@ zfs_dd_lookup(znode_t *dzp, znode_t **zp
 	    SA_ZPL_PARENT(zfsvfs), &parent, sizeof (parent))) != 0)
 		return (error);
 
-	/*
-	 * If we are a snapshot mounted under .zfs, return
-	 * the snapshot directory.
-	 */
-	if (parent == dzp->z_id && zfsvfs->z_parent != zfsvfs) {
-		error = zfsctl_root_lookup(zfsvfs->z_parent->z_ctldir,
-		    "snapshot", &vp, NULL, 0, NULL, kcred,
-		    NULL, NULL, NULL);
-		if (error == 0)
-			zp = VTOZ(vp);
-	} else {
-		error = zfs_zget(zfsvfs, parent, &zp);
-	}
+	error = zfs_zget(zfsvfs, parent, &zp);
 	if (error == 0)
 		*zpp = zp;
 	return (error);
@@ -222,8 +209,6 @@ zfs_dirlook(znode_t *dzp, const char *na
 		*zpp = dzp;
 	} else if (name[0] == '.' && name[1] == '.' && name[2] == 0) {
 		error = zfs_dd_lookup(dzp, zpp);
-	} else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) {
-		*zpp = VTOZ(zfsctl_root(dzp));
 	} else {
 		error = zfs_dirent_lookup(dzp, name, &zp, ZEXISTS);
 		if (error == 0) {

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Sat Aug  6 08:23:36 2016	(r303790)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Sat Aug  6 11:02:07 2016	(r303791)
@@ -1605,6 +1605,39 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode
 		return (SET_ERROR(EILSEQ));
 	}
 
+
+	/*
+	 * First handle the special cases.
+	 */
+	if ((cnp->cn_flags & ISDOTDOT) != 0) {
+		/*
+		 * If we are a snapshot mounted under .zfs, return
+		 * the vp for the snapshot directory.
+		 */
+		if (zdp->z_id == zfsvfs->z_root && zfsvfs->z_parent != zfsvfs) {
+			error = zfsctl_root_lookup(zfsvfs->z_parent->z_ctldir,
+			    "snapshot", vpp, NULL, 0, NULL, kcred,
+			    NULL, NULL, NULL);
+			ZFS_EXIT(zfsvfs);
+			if (error == 0) {
+				error = zfs_lookup_lock(dvp, *vpp, nm,
+				    cnp->cn_lkflags);
+			}
+			goto out;
+		}
+	}
+	if (zfs_has_ctldir(zdp) && strcmp(nm, ZFS_CTLDIR_NAME) == 0) {
+		error = 0;
+		if ((cnp->cn_flags & ISLASTCN) != 0 && nameiop != LOOKUP)
+			error = SET_ERROR(ENOTSUP);
+		else
+			*vpp = zfsctl_root(zdp);
+		ZFS_EXIT(zfsvfs);
+		if (error == 0)
+			error = zfs_lookup_lock(dvp, *vpp, nm, cnp->cn_lkflags);
+		goto out;
+	}
+
 	/*
 	 * The loop is retry the lookup if the parent-child relationship
 	 * changes during the dot-dot locking complexities.
@@ -1653,6 +1686,7 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode
 		vput(ZTOV(zp));
 	}
 
+out:
 	if (error != 0)
 		*vpp = NULL;
 


More information about the svn-src-head mailing list