changeset 10431:a4572ce3df84 onnv_123

6870347 assertion failure in dmu_tx_willuse_space(): refcount_count(&tx->tx_space_written) + delta <= tx->tx
author Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM>
date Tue, 01 Sep 2009 11:05:39 +0530
parents e48d1848c913
children 72e9aabfc892
files usr/src/cmd/ztest/ztest.c usr/src/uts/common/fs/zfs/zap.c
diffstat 2 files changed, 104 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/ztest/ztest.c	Mon Aug 31 22:34:26 2009 -0700
+++ b/usr/src/cmd/ztest/ztest.c	Tue Sep 01 11:05:39 2009 +0530
@@ -168,6 +168,7 @@
 ztest_func_t ztest_dmu_write_parallel;
 ztest_func_t ztest_dmu_object_alloc_free;
 ztest_func_t ztest_zap;
+ztest_func_t ztest_fzap;
 ztest_func_t ztest_zap_parallel;
 ztest_func_t ztest_traverse;
 ztest_func_t ztest_dsl_prop_get_set;
@@ -204,6 +205,7 @@
 	{ ztest_dmu_write_parallel,		30,	&zopt_always	},
 	{ ztest_dmu_object_alloc_free,		1,	&zopt_always	},
 	{ ztest_zap,				30,	&zopt_always	},
+	{ ztest_fzap,				30,	&zopt_always	},
 	{ ztest_zap_parallel,			100,	&zopt_always	},
 	{ ztest_dsl_prop_get_set,		1,	&zopt_sometimes	},
 	{ ztest_dmu_objset_create_destroy,	1,	&zopt_sometimes },
@@ -2944,6 +2946,102 @@
 	dmu_tx_commit(tx);
 }
 
+/*
+ * Testcase to test the upgrading of a microzap to fatzap.
+ */
+void
+ztest_fzap(ztest_args_t *za)
+{
+	objset_t *os = za->za_os;
+	uint64_t object;
+	uint64_t value;
+	dmu_tx_t *tx;
+	int i, error;
+	char osname[MAXNAMELEN];
+	char *name = "aaa";
+	char entname[20];
+
+	dmu_objset_name(os, osname);
+
+	/*
+	 * Create a new object if necessary, and record it in the directory.
+	 */
+	VERIFY(0 == dmu_read(os, ZTEST_DIROBJ, za->za_diroff,
+	    sizeof (uint64_t), &object, DMU_READ_PREFETCH));
+
+	if (object == 0) {
+		tx = dmu_tx_create(os);
+		dmu_tx_hold_write(tx, ZTEST_DIROBJ, za->za_diroff,
+		    sizeof (uint64_t));
+		dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, TRUE, NULL);
+		error = dmu_tx_assign(tx, TXG_WAIT);
+		if (error) {
+			ztest_record_enospc("create zap test obj");
+			dmu_tx_abort(tx);
+			return;
+		}
+		object = zap_create(os, DMU_OT_ZAP_OTHER, DMU_OT_NONE, 0, tx);
+		if (error) {
+			fatal(0, "zap_create('%s', %llu) = %d",
+			    osname, object, error);
+		}
+		ASSERT(object != 0);
+		dmu_write(os, ZTEST_DIROBJ, za->za_diroff,
+		    sizeof (uint64_t), &object, tx);
+		dmu_tx_commit(tx);
+	}
+
+	/*
+	 * Add entries to this ZAP amd make sure it spills over
+	 * and gets upgraded to a fatzap. Also, since we are adding
+	 * 2050 entries we should see ptrtbl growth and leaf-block
+	 * split.
+	 */
+	for (i = 0; i < 2050; i++) {
+		(void) sprintf(entname, "%s-%d", name, i);
+		value = i;
+
+		tx = dmu_tx_create(os);
+		dmu_tx_hold_zap(tx, object, TRUE, entname);
+		error = dmu_tx_assign(tx, TXG_WAIT);
+
+		if (error) {
+			ztest_record_enospc("create zap entry");
+			dmu_tx_abort(tx);
+			return;
+		}
+		error = zap_add(os, object, entname, sizeof (uint64_t),
+		    1, &value, tx);
+
+		ASSERT(error == 0 || error == EEXIST);
+		dmu_tx_commit(tx);
+	}
+
+	/*
+	 * Once in a while, destroy the object.
+	 */
+	if (ztest_random(1000) != 0)
+		return;
+
+	tx = dmu_tx_create(os);
+	dmu_tx_hold_write(tx, ZTEST_DIROBJ, za->za_diroff, sizeof (uint64_t));
+	dmu_tx_hold_free(tx, object, 0, DMU_OBJECT_END);
+	error = dmu_tx_assign(tx, TXG_WAIT);
+	if (error) {
+		ztest_record_enospc("destroy zap object");
+		dmu_tx_abort(tx);
+		return;
+	}
+	error = zap_destroy(os, object, tx);
+	if (error)
+		fatal(0, "zap_destroy('%s', %llu) = %d",
+		    osname, object, error);
+	object = 0;
+	dmu_write(os, ZTEST_DIROBJ, za->za_diroff, sizeof (uint64_t),
+	    &object, tx);
+	dmu_tx_commit(tx);
+}
+
 void
 ztest_zap_parallel(ztest_args_t *za)
 {
--- a/usr/src/uts/common/fs/zfs/zap.c	Mon Aug 31 22:34:26 2009 -0700
+++ b/usr/src/uts/common/fs/zfs/zap.c	Tue Sep 01 11:05:39 2009 +0530
@@ -1169,9 +1169,9 @@
 	 * Account for the header block of the fatzap.
 	 */
 	if (!add && dmu_buf_freeable(zap->zap_dbuf)) {
-		tooverwrite += zap->zap_dbuf->db_size;
+		*tooverwrite += zap->zap_dbuf->db_size;
 	} else {
-		towrite += zap->zap_dbuf->db_size;
+		*towrite += zap->zap_dbuf->db_size;
 	}
 
 	/*
@@ -1184,9 +1184,9 @@
 	 */
 	if (add) {
 		if (zap->zap_f.zap_phys->zap_ptrtbl.zt_blk == 0)
-			towrite += zap->zap_dbuf->db_size;
+			*towrite += zap->zap_dbuf->db_size;
 		else
-			towrite += (zap->zap_dbuf->db_size * 3);
+			*towrite += (zap->zap_dbuf->db_size * 3);
 	}
 
 	/*
@@ -1199,13 +1199,13 @@
 	}
 
 	if (!add && dmu_buf_freeable(l->l_dbuf)) {
-		tooverwrite += l->l_dbuf->db_size;
+		*tooverwrite += l->l_dbuf->db_size;
 	} else {
 		/*
 		 * If this an add operation, the leaf block could split.
 		 * Hence, we need to account for an additional leaf block.
 		 */
-		towrite += (add ? 2 : 1) * l->l_dbuf->db_size;
+		*towrite += (add ? 2 : 1) * l->l_dbuf->db_size;
 	}
 
 	zap_put_leaf(l);