changeset 10693:aaa91fcac595

6871683 ztest should exercise deferred destroy
author Chris Kirby <chris.kirby@sun.com>
date Wed, 30 Sep 2009 11:27:15 -0600
parents ab0b8119c0e1
children 584d721decf9
files usr/src/cmd/ztest/ztest.c usr/src/uts/common/fs/zfs/zfs_ioctl.c usr/src/uts/common/fs/zfs/zvol.c
diffstat 3 files changed, 117 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/ztest/ztest.c	Wed Sep 30 12:12:33 2009 -0400
+++ b/usr/src/cmd/ztest/ztest.c	Wed Sep 30 11:27:15 2009 -0600
@@ -185,6 +185,7 @@
 ztest_func_t ztest_vdev_add_remove;
 ztest_func_t ztest_vdev_aux_add_remove;
 ztest_func_t ztest_scrub;
+ztest_func_t ztest_dmu_snapshot_hold;
 
 typedef struct ztest_info {
 	ztest_func_t	*zi_func;	/* test function */
@@ -215,6 +216,7 @@
 	{ ztest_dmu_snapshot_create_destroy,	1,	&zopt_sometimes },
 	{ ztest_spa_create_destroy,		1,	&zopt_sometimes },
 	{ ztest_fault_inject,			1,	&zopt_sometimes	},
+	{ ztest_dmu_snapshot_hold,		1,	&zopt_sometimes	},
 	{ ztest_spa_rename,			1,	&zopt_rarely	},
 	{ ztest_vdev_attach_detach,		1,	&zopt_rarely	},
 	{ ztest_vdev_LUN_growth,		1,	&zopt_rarely	},
@@ -3468,6 +3470,119 @@
 }
 
 /*
+ * Test snapshot hold/release and deferred destroy.
+ */
+void
+ztest_dmu_snapshot_hold(ztest_args_t *za)
+{
+	int error;
+	objset_t *os = za->za_os;
+	objset_t *origin;
+	uint64_t curval = za->za_instance;
+	char snapname[100];
+	char fullname[100];
+	char clonename[100];
+	char tag[100];
+	char osname[MAXNAMELEN];
+
+	(void) rw_rdlock(&ztest_shared->zs_name_lock);
+
+	dmu_objset_name(os, osname);
+
+	(void) snprintf(snapname, 100, "sh1_%llu", curval);
+	(void) snprintf(fullname, 100, "%s@%s", osname, snapname);
+	(void) snprintf(clonename, 100, "%s/ch1_%llu", osname, curval);
+	(void) snprintf(tag, 100, "%tag_%llu", curval);
+
+	/*
+	 * Clean up from any previous run.
+	 */
+	(void) dmu_objset_destroy(clonename, B_FALSE);
+	(void) dsl_dataset_user_release(osname, snapname, tag, B_FALSE);
+	(void) dmu_objset_destroy(fullname, B_FALSE);
+
+	/*
+	 * Create snapshot, clone it, mark snap for deferred destroy,
+	 * destroy clone, verify snap was also destroyed.
+	 */
+	error = dmu_objset_snapshot(osname, snapname, NULL, FALSE);
+	if (error) {
+		if (error == ENOSPC) {
+			ztest_record_enospc("dmu_objset_snapshot");
+			goto out;
+		}
+		fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error);
+	}
+
+	error = dmu_objset_hold(fullname, FTAG, &origin);
+	if (error)
+		fatal(0, "dmu_objset_hold(%s) = %d", fullname, error);
+
+	error = dmu_objset_clone(clonename, dmu_objset_ds(origin), 0);
+	dmu_objset_rele(origin, FTAG);
+	if (error) {
+		if (error == ENOSPC) {
+			ztest_record_enospc("dmu_objset_clone");
+			goto out;
+		}
+		fatal(0, "dmu_objset_clone(%s) = %d", clonename, error);
+	}
+
+	error = dmu_objset_destroy(fullname, B_TRUE);
+	if (error) {
+		fatal(0, "dmu_objset_destroy(%s, B_TRUE) = %d",
+		    fullname, error);
+	}
+
+	error = dmu_objset_destroy(clonename, B_FALSE);
+	if (error)
+		fatal(0, "dmu_objset_destroy(%s) = %d", clonename, error);
+
+	error = dmu_objset_hold(fullname, FTAG, &origin);
+	if (error != ENOENT)
+		fatal(0, "dmu_objset_hold(%s) = %d", fullname, error);
+
+	/*
+	 * Create snapshot, add temporary hold, verify that we can't
+	 * destroy a held snapshot, mark for deferred destroy,
+	 * release hold, verify snapshot was destroyed.
+	 */
+	error = dmu_objset_snapshot(osname, snapname, NULL, FALSE);
+	if (error) {
+		if (error == ENOSPC) {
+			ztest_record_enospc("dmu_objset_snapshot");
+			goto out;
+		}
+		fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error);
+	}
+
+	error = dsl_dataset_user_hold(osname, snapname, tag, B_FALSE, B_TRUE);
+	if (error)
+		fatal(0, "dsl_dataset_user_hold(%s)", fullname, tag);
+
+	error = dmu_objset_destroy(fullname, B_FALSE);
+	if (error != EBUSY) {
+		fatal(0, "dmu_objset_destroy(%s, B_FALSE) = %d",
+		    fullname, error);
+	}
+
+	error = dmu_objset_destroy(fullname, B_TRUE);
+	if (error) {
+		fatal(0, "dmu_objset_destroy(%s, B_TRUE) = %d",
+		    fullname, error);
+	}
+
+	error = dsl_dataset_user_release(osname, snapname, tag, B_FALSE);
+	if (error)
+		fatal(0, "dsl_dataset_user_release(%s)", fullname, tag);
+
+	VERIFY(dmu_objset_hold(fullname, FTAG, &origin) == ENOENT);
+
+out:
+	(void) rw_unlock(&ztest_shared->zs_name_lock);
+}
+
+/*
  * Inject random faults into the on-disk data.
  */
 void
--- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c	Wed Sep 30 12:12:33 2009 -0400
+++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c	Wed Sep 30 11:27:15 2009 -0600
@@ -2567,7 +2567,7 @@
 
 	err = dmu_objset_destroy(zc->zc_name, zc->zc_defer_destroy);
 	if (zc->zc_objset_type == DMU_OST_ZVOL && err == 0)
-		zvol_remove_minor(zc->zc_name);
+		(void) zvol_remove_minor(zc->zc_name);
 	return (err);
 }
 
--- a/usr/src/uts/common/fs/zfs/zvol.c	Wed Sep 30 12:12:33 2009 -0400
+++ b/usr/src/uts/common/fs/zfs/zvol.c	Wed Sep 30 11:27:15 2009 -0600
@@ -1771,7 +1771,7 @@
 		dmu_tx_abort(tx);
 		return (error);
 	}
-	dmu_object_set_blocksize(os, ZVOL_OBJ, vbs, 0, tx);
+	(void) dmu_object_set_blocksize(os, ZVOL_OBJ, vbs, 0, tx);
 	dmu_tx_commit(tx);
 
 	return (0);