svn commit: r201646 - in stable/7/sys/cddl: compat/opensolaris/kern contrib/opensolaris/uts/common/fs/zfs contrib/opensolaris/uts/common/fs/zfs/sys

Alexander Leidinger netchild at FreeBSD.org
Wed Jan 6 13:56:50 UTC 2010


Author: netchild
Date: Wed Jan  6 13:56:49 2010
New Revision: 201646
URL: http://svn.freebsd.org/changeset/base/201646

Log:
  MFC several ZFS related commits:
  
  r196662:
  ---snip---
      Add missing mountpoint vnode locking.
  
      This fixes panic on assertion with DEBUG_VFS_LOCKS and vfs.usermount=1 when
      regular user tries to mount dataset owned by him.
  ---snip---
  
  r196703:
  ---snip---
      Backport the 'dirtying dbuf' panic fix from newer ZFS version.
  
      Reported by:	Thomas Backman <serenity at exscape.org>
  ---snip---
  
  r196919:
  ---snip---
      bzero() on-stack argument, so mutex_init() won't misinterpret that the
      lock is already initialized if we have some garbage on the stack.
  
      PR:			kern/135480
      Reported by:	Emil Mikulic <emikulic at gmail.com>
  ---snip---
  
  r196927:
  ---snip---
      Changing provider size is not really supported by GEOM, but doing so when
      provider is closed should be ok.
  
      When administrator requests to change ZVOL size do it immediately if ZVOL
      is closed or do it on last ZVOL close.
  
      PR:			kern/136942
      Requested by:	Bernard Buri <bsd at ask-us.at>
  ---snip---
  
  r196943:
  ---snip---
      - Avoid holding mutex around M_WAITOK allocations.
      - Add locking for mnt_opt field.
  ---snip---
  
  r196944:
  ---snip---
      Don't recheck ownership on update mount. This will eliminate LOR between
      vfs_busy() and mount mutex. We check ownership in vfs_domount() anyway.
  
      Noticed by:	kib
      Reviewed by:	kib
  ---snip---
  
  r196954:
  ---snip---
      If we have to use avl_find(), optimize a bit and use avl_insert() instead of
      avl_add() (the latter is actually a wrapper around avl_find() + avl_insert()).
  
      Fix similar case in the code that is currently commented out.
  ---snip---
  Note: This also seems to fix a previous merge hickup.
  
  r196965:
  ---snip---
      Fix reference count leak for a case where snapshot's mount point is updated.
      Such situation is not supported.
  
      This problem was triggered by something like this:
  
  	# zpool create tank da0
  	# zfs snapshot tank at snap
  	# cd /tank/.zfs/snapshot/snap  (this will mount the snapshot)
  	# cd
  	# mount -u nosuid /tank/.zfs/snapshot/snap  (refcount leak)
  	# zpool export tank
  	cannot export 'tank': pool is busy
  ---snip---
  
  r196985:
  ---snip---
      Only log successful commands! Without this fix we log even unsuccessful
      commands executed by unprivileged users. Action is not really taken, but it is
      logged to pool history, which might be confusing.
  
      Reported by:	Denis Ahrens <denis at h3q.com>
  ---snip---
  
  r197151:
  ---snip---
      Be sure not to overflow struct fid.
  ---snip---
  
  r197152:
  ---snip---
      Extend scope of the z_teardown_lock lock for consistency and "just in case".
  ---snip---
  
  r200124:
  ---snip---
      Avoid using additional variable for storing an error if we are not going
      to do anything with it.
  ---snip---
  
  r200158:
  ---snip---
     We have to eventually look for provider without checking guid as this is need
     for attaching when there is no metadata yet.
  
     Before r200125 the order of looking for providers was wrong. It was:
     1. Find provider by name.
     2. Find provider by guid.
     3. Find provider by name and guid.
  
     Where it should have been:
     1. Find provider by name and guid.
     2. Find provider by guid.
     3. Find provider by name.
  ---snip---
  Note: This was already there, but it was not recorded as merged. This commit
  fixes a mis-merge (reversed logic).

Modified:
  stable/7/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c
==============================================================================
--- stable/7/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c	Wed Jan  6 13:14:37 2010	(r201645)
+++ stable/7/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c	Wed Jan  6 13:56:49 2010	(r201646)
@@ -45,20 +45,33 @@ vfs_setmntopt(vfs_t *vfsp, const char *n
 {
 	struct vfsopt *opt;
 	size_t namesize;
+	int locked;
+
+	if (!(locked = mtx_owned(MNT_MTX(vfsp))))
+		MNT_ILOCK(vfsp);
 
 	if (vfsp->mnt_opt == NULL) {
-		vfsp->mnt_opt = malloc(sizeof(*vfsp->mnt_opt), M_MOUNT, M_WAITOK);
-		TAILQ_INIT(vfsp->mnt_opt);
+		void *opts;
+
+		MNT_IUNLOCK(vfsp);
+		opts = malloc(sizeof(*vfsp->mnt_opt), M_MOUNT, M_WAITOK);
+		MNT_ILOCK(vfsp);
+		if (vfsp->mnt_opt == NULL) {
+			vfsp->mnt_opt = opts;
+			TAILQ_INIT(vfsp->mnt_opt);
+		} else {
+			free(opts, M_MOUNT);
+		}
 	}
 
-	opt = malloc(sizeof(*opt), M_MOUNT, M_WAITOK);
+	MNT_IUNLOCK(vfsp);
 
+	opt = malloc(sizeof(*opt), M_MOUNT, M_WAITOK);
 	namesize = strlen(name) + 1;
 	opt->name = malloc(namesize, M_MOUNT, M_WAITOK);
 	strlcpy(opt->name, name, namesize);
 	opt->pos = -1;
 	opt->seen = 1;
-
 	if (arg == NULL) {
 		opt->value = NULL;
 		opt->len = 0;
@@ -67,16 +80,23 @@ vfs_setmntopt(vfs_t *vfsp, const char *n
 		opt->value = malloc(opt->len, M_MOUNT, M_WAITOK);
 		bcopy(arg, opt->value, opt->len);
 	}
-	/* TODO: Locking. */
+
+	MNT_ILOCK(vfsp);
 	TAILQ_INSERT_TAIL(vfsp->mnt_opt, opt, link);
+	if (!locked)
+		MNT_IUNLOCK(vfsp);
 }
 
 void
 vfs_clearmntopt(vfs_t *vfsp, const char *name)
 {
+	int locked;
 
-	/* TODO: Locking. */
+	if (!(locked = mtx_owned(MNT_MTX(vfsp))))
+		MNT_ILOCK(vfsp);
 	vfs_deleteopt(vfsp->mnt_opt, name);
+	if (!locked)
+		MNT_IUNLOCK(vfsp);
 }
 
 int

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c	Wed Jan  6 13:14:37 2010	(r201645)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c	Wed Jan  6 13:56:49 2010	(r201646)
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -864,10 +864,11 @@ restore_object(struct restorearg *ra, ob
 		/* currently allocated, want to be allocated */
 		dmu_tx_hold_bonus(tx, drro->drr_object);
 		/*
-		 * We may change blocksize, so need to
-		 * hold_write
+		 * We may change blocksize and delete old content,
+		 * so need to hold_write and hold_free.
 		 */
 		dmu_tx_hold_write(tx, drro->drr_object, 0, 1);
+		dmu_tx_hold_free(tx, drro->drr_object, 0, DMU_OBJECT_END);
 		err = dmu_tx_assign(tx, TXG_WAIT);
 		if (err) {
 			dmu_tx_abort(tx);

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c	Wed Jan  6 13:14:37 2010	(r201645)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c	Wed Jan  6 13:56:49 2010	(r201646)
@@ -415,7 +415,7 @@ void
 dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
     dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
 {
-	int i, old_nblkptr;
+	int i, nblkptr;
 	dmu_buf_impl_t *db = NULL;
 
 	ASSERT3U(blocksize, >=, SPA_MINBLOCKSIZE);
@@ -445,6 +445,8 @@ dnode_reallocate(dnode_t *dn, dmu_object
 		dnode_free_range(dn, 0, -1ULL, tx);
 	}
 
+	nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
+
 	/* change blocksize */
 	rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
 	if (blocksize != dn->dn_datablksz &&
@@ -457,6 +459,8 @@ dnode_reallocate(dnode_t *dn, dmu_object
 	dnode_setdirty(dn, tx);
 	dn->dn_next_bonuslen[tx->tx_txg&TXG_MASK] = bonuslen;
 	dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
+	if (dn->dn_nblkptr != nblkptr)
+		dn->dn_next_nblkptr[tx->tx_txg&TXG_MASK] = nblkptr;
 	rw_exit(&dn->dn_struct_rwlock);
 	if (db)
 		dbuf_rele(db, FTAG);
@@ -466,19 +470,15 @@ dnode_reallocate(dnode_t *dn, dmu_object
 
 	/* change bonus size and type */
 	mutex_enter(&dn->dn_mtx);
-	old_nblkptr = dn->dn_nblkptr;
 	dn->dn_bonustype = bonustype;
 	dn->dn_bonuslen = bonuslen;
-	dn->dn_nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
+	dn->dn_nblkptr = nblkptr;
 	dn->dn_checksum = ZIO_CHECKSUM_INHERIT;
 	dn->dn_compress = ZIO_COMPRESS_INHERIT;
 	ASSERT3U(dn->dn_nblkptr, <=, DN_MAX_NBLKPTR);
 
-	/* XXX - for now, we can't make nblkptr smaller */
-	ASSERT3U(dn->dn_nblkptr, >=, old_nblkptr);
-
-	/* fix up the bonus db_size if dn_nblkptr has changed */
-	if (dn->dn_bonus && dn->dn_bonuslen != old_nblkptr) {
+	/* fix up the bonus db_size */
+	if (dn->dn_bonus) {
 		dn->dn_bonus->db.db_size =
 		    DN_MAX_BONUSLEN - (dn->dn_nblkptr-1) * sizeof (blkptr_t);
 		ASSERT(dn->dn_bonuslen <= dn->dn_bonus->db.db_size);

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c	Wed Jan  6 13:14:37 2010	(r201645)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c	Wed Jan  6 13:56:49 2010	(r201646)
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/zfs_context.h>
 #include <sys/dbuf.h>
 #include <sys/dnode.h>
@@ -534,18 +532,12 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx)
 			/* XXX shouldn't the phys already be zeroed? */
 			bzero(dnp, DNODE_CORE_SIZE);
 			dnp->dn_nlevels = 1;
+			dnp->dn_nblkptr = dn->dn_nblkptr;
 		}
 
-		if (dn->dn_nblkptr > dnp->dn_nblkptr) {
-			/* zero the new blkptrs we are gaining */
-			bzero(dnp->dn_blkptr + dnp->dn_nblkptr,
-			    sizeof (blkptr_t) *
-			    (dn->dn_nblkptr - dnp->dn_nblkptr));
-		}
 		dnp->dn_type = dn->dn_type;
 		dnp->dn_bonustype = dn->dn_bonustype;
 		dnp->dn_bonuslen = dn->dn_bonuslen;
-		dnp->dn_nblkptr = dn->dn_nblkptr;
 	}
 
 	ASSERT(dnp->dn_nlevels > 1 ||
@@ -605,6 +597,30 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx)
 		return;
 	}
 
+	if (dn->dn_next_nblkptr[txgoff]) {
+		/* this should only happen on a realloc */
+		ASSERT(dn->dn_allocated_txg == tx->tx_txg);
+		if (dn->dn_next_nblkptr[txgoff] > dnp->dn_nblkptr) {
+			/* zero the new blkptrs we are gaining */
+			bzero(dnp->dn_blkptr + dnp->dn_nblkptr,
+			    sizeof (blkptr_t) *
+			    (dn->dn_next_nblkptr[txgoff] - dnp->dn_nblkptr));
+#ifdef ZFS_DEBUG
+		} else {
+			int i;
+			ASSERT(dn->dn_next_nblkptr[txgoff] < dnp->dn_nblkptr);
+			/* the blkptrs we are losing better be unallocated */
+			for (i = dn->dn_next_nblkptr[txgoff];
+			    i < dnp->dn_nblkptr; i++)
+				ASSERT(BP_IS_HOLE(&dnp->dn_blkptr[i]));
+#endif
+		}
+		mutex_enter(&dn->dn_mtx);
+		dnp->dn_nblkptr = dn->dn_next_nblkptr[txgoff];
+		dn->dn_next_nblkptr[txgoff] = 0;
+		mutex_exit(&dn->dn_mtx);
+	}
+
 	if (dn->dn_next_nlevels[txgoff]) {
 		dnode_increase_indirection(dn, tx);
 		dn->dn_next_nlevels[txgoff] = 0;

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c	Wed Jan  6 13:14:37 2010	(r201645)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c	Wed Jan  6 13:56:49 2010	(r201646)
@@ -1420,6 +1420,7 @@ dsl_dataset_drain_refs(dsl_dataset_t *ds
 {
 	struct refsarg arg;
 
+	bzero(&arg, sizeof(arg));
 	mutex_init(&arg.lock, NULL, MUTEX_DEFAULT, NULL);
 	cv_init(&arg.cv, NULL, CV_DEFAULT, NULL);
 	arg.gone = FALSE;

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h	Wed Jan  6 13:14:37 2010	(r201645)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h	Wed Jan  6 13:56:49 2010	(r201646)
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -160,6 +160,7 @@ typedef struct dnode {
 	uint16_t dn_datablkszsec;	/* in 512b sectors */
 	uint32_t dn_datablksz;		/* in bytes */
 	uint64_t dn_maxblkid;
+	uint8_t dn_next_nblkptr[TXG_SIZE];
 	uint8_t dn_next_nlevels[TXG_SIZE];
 	uint8_t dn_next_indblkshift[TXG_SIZE];
 	uint16_t dn_next_bonuslen[TXG_SIZE];

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c	Wed Jan  6 13:14:37 2010	(r201645)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c	Wed Jan  6 13:56:49 2010	(r201646)
@@ -293,7 +293,7 @@ vdev_geom_read_guid(struct g_consumer *c
 	uint64_t psize;
 	off_t offset, size;
 	uint64_t guid;
-	int error, l, len;
+	int l, len;
 
 	g_topology_assert_not();
 
@@ -316,8 +316,7 @@ vdev_geom_read_guid(struct g_consumer *c
 		if ((offset % pp->sectorsize) != 0)
 			continue;
 
-		error = vdev_geom_io(cp, BIO_READ, label, offset, size);
-		if (error != 0)
+		if (vdev_geom_io(cp, BIO_READ, label, offset, size) != 0)
 			continue;
 		buf = label->vl_vdev_phys.vp_nvlist;
 
@@ -502,7 +501,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psi
 
 	if ((owned = mtx_owned(&Giant)))
 		mtx_unlock(&Giant);
-	cp = vdev_geom_open_by_path(vd, 0);
+	cp = vdev_geom_open_by_path(vd, 1);
 	if (cp == NULL) {
 		/*
 		 * The device at vd->vdev_path doesn't have the expected guid.
@@ -512,7 +511,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psi
 		cp = vdev_geom_open_by_guid(vd);
 	}
 	if (cp == NULL)
-		cp = vdev_geom_open_by_path(vd, 1);
+		cp = vdev_geom_open_by_path(vd, 0);
 	if (cp == NULL) {
 		ZFS_LOG(1, "Provider %s not found.", vd->vdev_path);
 		vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c	Wed Jan  6 13:14:37 2010	(r201645)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c	Wed Jan  6 13:56:49 2010	(r201646)
@@ -668,9 +668,12 @@ zfsctl_snapdir_remove(vnode_t *dvp, char
 	if (sep) {
 		avl_remove(&sdp->sd_snaps, sep);
 		err = zfsctl_unmount_snap(sep, MS_FORCE, cr);
-		if (err)
-			avl_add(&sdp->sd_snaps, sep);
-		else
+		if (err) {
+			avl_index_t where;
+
+			if (avl_find(&sdp->sd_snaps, sep, &where) == NULL)
+				avl_insert(&sdp->sd_snaps, sep, where);
+		} else
 			err = dmu_objset_destroy(snapname);
 	} else {
 		err = ENOENT;
@@ -1299,7 +1302,17 @@ zfsctl_umount_snapshots(vfs_t *vfsp, int
 		if (vn_ismntpt(sep->se_root)) {
 			error = zfsctl_unmount_snap(sep, fflags, cr);
 			if (error) {
-				avl_add(&sdp->sd_snaps, sep);
+				avl_index_t where;
+
+				/*
+				 * Before reinserting snapshot to the tree,
+				 * check if it was actually removed. For example
+				 * when snapshot mount point is busy, we will
+				 * have an error here, but there will be no need
+				 * to reinsert snapshot.
+				 */
+				if (avl_find(&sdp->sd_snaps, sep, &where) == NULL)
+					avl_insert(&sdp->sd_snaps, sep, where);
 				break;
 			}
 		}

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c	Wed Jan  6 13:14:37 2010	(r201645)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c	Wed Jan  6 13:56:49 2010	(r201646)
@@ -3022,8 +3022,10 @@ zfsdev_ioctl(struct cdev *dev, u_long cm
 	if (error == 0)
 		error = zfs_ioc_vec[vec].zvec_func(zc);
 
-	if (zfs_ioc_vec[vec].zvec_his_log == B_TRUE)
-		zfs_log_history(zc);
+	if (error == 0) {
+		if (zfs_ioc_vec[vec].zvec_his_log == B_TRUE)
+			zfs_log_history(zc);
+	}
 
 	return (error);
 }

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Wed Jan  6 13:14:37 2010	(r201645)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Wed Jan  6 13:56:49 2010	(r201646)
@@ -340,6 +340,13 @@ zfs_register_callbacks(vfs_t *vfsp)
 	os = zfsvfs->z_os;
 
 	/*
+	 * This function can be called for a snapshot when we update snapshot's
+	 * mount point, which isn't really supported.
+	 */
+	if (dmu_objset_is_snapshot(os))
+		return (EOPNOTSUPP);
+
+	/*
 	 * The act of registering our callbacks will destroy any mount
 	 * options we may have.  In order to enable temporary overrides
 	 * of mount options, we stash away the current values and
@@ -727,7 +734,10 @@ zfs_mount(vfs_t *vfsp, kthread_t *td)
 	error = secpolicy_fs_mount(cr, mvp, vfsp);
 	if (error) {
 		error = dsl_deleg_access(osname, ZFS_DELEG_PERM_MOUNT, cr);
-		if (error == 0) {
+		if (error != 0)
+			goto out;
+
+		if (!(vfsp->vfs_flag & MS_REMOUNT)) {
 			vattr_t		vattr;
 
 			/*
@@ -737,7 +747,9 @@ zfs_mount(vfs_t *vfsp, kthread_t *td)
 
 			vattr.va_mask = AT_UID;
 
+			vn_lock(mvp, LK_SHARED | LK_RETRY, td);
 			if (error = VOP_GETATTR(mvp, &vattr, cr, td)) {
+				VOP_UNLOCK(mvp, 0, td);
 				goto out;
 			}
 
@@ -749,18 +761,19 @@ zfs_mount(vfs_t *vfsp, kthread_t *td)
 			}
 #else
 			if (error = secpolicy_vnode_owner(mvp, cr, vattr.va_uid)) {
+				VOP_UNLOCK(mvp, 0, td);
 				goto out;
 			}
 
 			if (error = VOP_ACCESS(mvp, VWRITE, cr, td)) {
+				VOP_UNLOCK(mvp, 0, td);
 				goto out;
 			}
+			VOP_UNLOCK(mvp, 0, td);
 #endif
-
-			secpolicy_fs_mount_clearopts(cr, vfsp);
-		} else {
-			goto out;
 		}
+
+		secpolicy_fs_mount_clearopts(cr, vfsp);
 	}
 
 	/*
@@ -890,6 +903,9 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolea
 		 * 'z_parent' is self referential for non-snapshots.
 		 */
 		(void) dnlc_purge_vfsp(zfsvfs->z_parent->z_vfs, 0);
+#ifdef FREEBSD_NAMECACHE
+		cache_purgevfs(zfsvfs->z_parent->z_vfs);
+#endif
 	}
 
 	/*
@@ -1114,6 +1130,9 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int fla
 	return (err);
 }
 
+CTASSERT(SHORT_FID_LEN <= sizeof(struct fid));
+CTASSERT(LONG_FID_LEN <= sizeof(struct fid));
+
 static int
 zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp)
 {

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Wed Jan  6 13:14:37 2010	(r201645)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Wed Jan  6 13:56:49 2010	(r201646)
@@ -1186,8 +1186,6 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode
 		}
 	}
 
-	ZFS_EXIT(zfsvfs);
-
 	/* Translate errors and add SAVENAME when needed. */
 	if (cnp->cn_flags & ISLASTCN) {
 		switch (nameiop) {
@@ -1218,6 +1216,7 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode
 		if (error != 0) {
 			VN_RELE(*vpp);
 			*vpp = NULL;
+			ZFS_EXIT(zfsvfs);
 			return (error);
 		}
 	}
@@ -1239,6 +1238,8 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode
 	}
 #endif
 
+	ZFS_EXIT(zfsvfs);
+
 	return (error);
 }
 

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c	Wed Jan  6 13:14:37 2010	(r201645)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c	Wed Jan  6 13:56:49 2010	(r201646)
@@ -153,7 +153,22 @@ static int zvol_dump_init(zvol_state_t *
 static void
 zvol_size_changed(zvol_state_t *zv, major_t maj)
 {
+	struct g_provider *pp;
+
+	g_topology_assert();
 
+	pp = zv->zv_provider;
+	if (pp == NULL)
+		return;
+	if (zv->zv_volsize == pp->mediasize)
+		return;
+	/*
+	 * Changing provider size is not really supported by GEOM, but it
+	 * should be safe when provider is closed.
+	 */
+	if (zv->zv_total_opens > 0)
+		return;
+	pp->mediasize = zv->zv_volsize;
 }
 
 int
@@ -263,6 +278,7 @@ zvol_access(struct g_provider *pp, int a
 	}
 
 	zv->zv_total_opens += acr + acw + ace;
+	zvol_size_changed(zv, 0);
 
 	mutex_exit(&zvol_state_lock);
 
@@ -1070,11 +1086,6 @@ zvol_set_volblocksize(const char *name, 
 		if (error == ENOTSUP)
 			error = EBUSY;
 		dmu_tx_commit(tx);
-		/* XXX: Not supported. */
-#if 0
-		if (error == 0)
-			zv->zv_provider->sectorsize = zc->zc_volblocksize;
-#endif
 	}
 end:
 	mutex_exit(&zvol_state_lock);


More information about the svn-src-all mailing list