changeset 13780:6da32a929222

3100 zvol rename fails with EBUSY when dirty 3103 zfs mdb module may get wrong refcount struct Reviewed by: Christopher Siden <chris.siden@delphix.com> Reviewed by: Adam H. Leventhal <ahl@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Approved by: Eric Schrock <eric.schrock@delphix.com>
author Matthew Ahrens <mahrens@delphix.com>
date Fri, 24 Aug 2012 07:12:46 -0700
parents bf40125f4b37
children 64a1ab954737
files usr/src/cmd/mdb/common/modules/zfs/zfs.c usr/src/lib/libzfs/common/libzfs_dataset.c usr/src/uts/common/fs/zfs/dmu_objset.c usr/src/uts/common/fs/zfs/dsl_dataset.c usr/src/uts/common/fs/zfs/dsl_dir.c usr/src/uts/common/fs/zfs/dsl_pool.c usr/src/uts/common/fs/zfs/sys/dmu_objset.h usr/src/uts/common/fs/zfs/sys/dsl_dataset.h usr/src/uts/common/fs/zfs/zfs_vfsops.c usr/src/uts/common/fs/zfs/zvol.c
diffstat 10 files changed, 34 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/mdb/common/modules/zfs/zfs.c	Sun Jul 08 03:19:56 2012 +0100
+++ b/usr/src/cmd/mdb/common/modules/zfs/zfs.c	Fri Aug 24 07:12:46 2012 -0700
@@ -2338,7 +2338,14 @@
 		return (DCMD_USAGE);
 
 	if (!gotid) {
-		if (mdb_ctf_lookup_by_name("struct refcount", &rc_id) == -1) {
+		/*
+		 * The refcount structure is different when compiled debug
+		 * vs nondebug.  Therefore, we want to make sure we get the
+		 * refcount definition from the ZFS module, in case it has
+		 * been compiled debug but genunix is nondebug.
+		 */
+		if (mdb_ctf_lookup_by_name("struct " ZFS_OBJ_NAME "`refcount",
+		    &rc_id) == -1) {
 			mdb_warn("couldn't find struct refcount");
 			return (DCMD_ERR);
 		}
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c	Sun Jul 08 03:19:56 2012 +0100
+++ b/usr/src/lib/libzfs/common/libzfs_dataset.c	Fri Aug 24 07:12:46 2012 -0700
@@ -3511,7 +3511,7 @@
 	    zhp->zfs_type == ZFS_TYPE_VOLUME);
 
 	/*
-	 * Destroy all recent snapshots and its dependends.
+	 * Destroy all recent snapshots and their dependents.
 	 */
 	cb.cb_force = force;
 	cb.cb_target = snap->zfs_name;
--- a/usr/src/uts/common/fs/zfs/dmu_objset.c	Sun Jul 08 03:19:56 2012 +0100
+++ b/usr/src/uts/common/fs/zfs/dmu_objset.c	Fri Aug 24 07:12:46 2012 -0700
@@ -1236,15 +1236,6 @@
 	    !list_is_empty(&os->os_free_dnodes[txg & TXG_MASK]));
 }
 
-boolean_t
-dmu_objset_is_dirty_anywhere(objset_t *os)
-{
-	for (int t = 0; t < TXG_SIZE; t++)
-		if (dmu_objset_is_dirty(os, t))
-			return (B_TRUE);
-	return (B_FALSE);
-}
-
 static objset_used_cb_t *used_cbs[DMU_OST_NUMTYPES];
 
 void
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c	Sun Jul 08 03:19:56 2012 +0100
+++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c	Fri Aug 24 07:12:46 2012 -0700
@@ -1210,6 +1210,17 @@
 	}
 }
 
+boolean_t
+dsl_dataset_is_dirty(dsl_dataset_t *ds)
+{
+	for (int t = 0; t < TXG_SIZE; t++) {
+		if (txg_list_member(&ds->ds_dir->dd_pool->dp_dirty_datasets,
+		    ds, t))
+			return (B_TRUE);
+	}
+	return (B_FALSE);
+}
+
 /*
  * The unique space in the head dataset can be calculated by subtracting
  * the space used in the most recent snapshot, that is still being used
@@ -3432,9 +3443,6 @@
 	if (ds->ds_quota != effective_value) {
 		dmu_buf_will_dirty(ds->ds_dbuf, tx);
 		ds->ds_quota = effective_value;
-
-		spa_history_log_internal_ds(ds, "set refquota", tx,
-		    "refquota=%lld", (longlong_t)ds->ds_quota);
 	}
 }
 
@@ -3538,9 +3546,6 @@
 
 	dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx);
 	mutex_exit(&ds->ds_dir->dd_lock);
-
-	spa_history_log_internal_ds(ds, "set refreservation", tx,
-	    "refreservation=%lld", (longlong_t)effective_value);
 }
 
 int
--- a/usr/src/uts/common/fs/zfs/dsl_dir.c	Sun Jul 08 03:19:56 2012 +0100
+++ b/usr/src/uts/common/fs/zfs/dsl_dir.c	Fri Aug 24 07:12:46 2012 -0700
@@ -1050,9 +1050,6 @@
 	mutex_enter(&dd->dd_lock);
 	dd->dd_phys->dd_quota = effective_value;
 	mutex_exit(&dd->dd_lock);
-
-	spa_history_log_internal_dd(dd, "set quota", tx,
-	    "quota=%lld", (longlong_t)effective_value);
 }
 
 int
@@ -1172,9 +1169,6 @@
 	DSL_PROP_CHECK_PREDICTION(dd, psa);
 
 	dsl_dir_set_reservation_sync_impl(dd, value, tx);
-
-	spa_history_log_internal_dd(dd, "set reservation", tx,
-	    "reservation=%lld", (longlong_t)value);
 }
 
 int
--- a/usr/src/uts/common/fs/zfs/dsl_pool.c	Sun Jul 08 03:19:56 2012 +0100
+++ b/usr/src/uts/common/fs/zfs/dsl_pool.c	Fri Aug 24 07:12:46 2012 -0700
@@ -126,8 +126,6 @@
 	dsl_dataset_t *ds;
 	uint64_t obj;
 
-	ASSERT(!dmu_objset_is_dirty_anywhere(dp->dp_meta_objset));
-
 	rw_enter(&dp->dp_config_rwlock, RW_WRITER);
 	err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
 	    DMU_POOL_ROOT_DATASET, sizeof (uint64_t), 1,
--- a/usr/src/uts/common/fs/zfs/sys/dmu_objset.h	Sun Jul 08 03:19:56 2012 +0100
+++ b/usr/src/uts/common/fs/zfs/sys/dmu_objset.h	Fri Aug 24 07:12:46 2012 -0700
@@ -152,7 +152,6 @@
 /* called from dsl */
 void dmu_objset_sync(objset_t *os, zio_t *zio, dmu_tx_t *tx);
 boolean_t dmu_objset_is_dirty(objset_t *os, uint64_t txg);
-boolean_t dmu_objset_is_dirty_anywhere(objset_t *os);
 objset_t *dmu_objset_create_impl(spa_t *spa, struct dsl_dataset *ds,
     blkptr_t *bp, dmu_objset_type_t type, dmu_tx_t *tx);
 int dmu_objset_open_impl(spa_t *spa, struct dsl_dataset *ds, blkptr_t *bp,
--- a/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h	Sun Jul 08 03:19:56 2012 +0100
+++ b/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h	Fri Aug 24 07:12:46 2012 -0700
@@ -262,6 +262,7 @@
     uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
 int dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap, dsl_dataset_t *last,
     uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
+boolean_t dsl_dataset_is_dirty(dsl_dataset_t *ds);
 
 int dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf);
 
--- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c	Sun Jul 08 03:19:56 2012 +0100
+++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c	Fri Aug 24 07:12:46 2012 -0700
@@ -1831,9 +1831,9 @@
 	/*
 	 * Evict cached data
 	 */
-	if (dmu_objset_is_dirty_anywhere(zfsvfs->z_os))
-		if (!(zfsvfs->z_vfs->vfs_flag & VFS_RDONLY))
-			txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), 0);
+	if (dsl_dataset_is_dirty(dmu_objset_ds(zfsvfs->z_os)) &&
+	    !(zfsvfs->z_vfs->vfs_flag & VFS_RDONLY))
+		txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), 0);
 	(void) dmu_objset_evict_dbufs(zfsvfs->z_os);
 
 	return (0);
--- a/usr/src/uts/common/fs/zfs/zvol.c	Sun Jul 08 03:19:56 2012 +0100
+++ b/usr/src/uts/common/fs/zfs/zvol.c	Fri Aug 24 07:12:46 2012 -0700
@@ -641,8 +641,18 @@
 {
 	zil_close(zv->zv_zilog);
 	zv->zv_zilog = NULL;
+
 	dmu_buf_rele(zv->zv_dbuf, zvol_tag);
 	zv->zv_dbuf = NULL;
+
+	/*
+	 * Evict cached data
+	 */
+	if (dsl_dataset_is_dirty(dmu_objset_ds(zv->zv_objset)) &&
+	    !(zv->zv_flags & ZVOL_RDONLY))
+		txg_wait_synced(dmu_objset_pool(zv->zv_objset), 0);
+	(void) dmu_objset_evict_dbufs(zv->zv_objset);
+
 	dmu_objset_disown(zv->zv_objset, zvol_tag);
 	zv->zv_objset = NULL;
 }