diff --git a/module/zfs/dmu_zfetch.c b/module/zfs/dmu_zfetch.c
index 6b5d58528f..fc3d23b874 100644
--- a/module/zfs/dmu_zfetch.c
+++ b/module/zfs/dmu_zfetch.c
@@ -203,20 +203,53 @@ dmu_zfetch_dofetch(zfetch_t *zf, zstream_t *zs)
 void
 dmu_zfetch_init(zfetch_t *zf, dnode_t *dno)
 {
-	if (zf == NULL) {
-		return;
-	}
-
 	zf->zf_dnode = dno;
 	zf->zf_stream_cnt = 0;
 	zf->zf_alloc_fail = 0;
+}
 
+/*
+ * Clean-up state associated with a zfetch structure.  This frees allocated
+ * structure members, empties the zf_stream tree, and generally makes things
+ * nice.  This doesn't free the zfetch_t itself, that's left to the caller.
+ */
+void
+dmu_zfetch_rele(zfetch_t *zf)
+{
+	zstream_t *zs;
+	zstream_t *zs_next;
+
+	for (zs = list_head(&zf->zf_stream); zs; zs = zs_next) {
+		zs_next = list_next(&zf->zf_stream, zs);
+
+		list_remove(&zf->zf_stream, zs);
+		mutex_destroy(&zs->zst_lock);
+		kmem_free(zs, sizeof (zstream_t));
+	}
+}
+
+/*
+ * Construct a zfetch structure.
+ */
+void
+dmu_zfetch_cons(zfetch_t *zf)
+{
 	list_create(&zf->zf_stream, sizeof (zstream_t),
 	    offsetof(zstream_t, zst_node));
 
 	rw_init(&zf->zf_rwlock, NULL, RW_DEFAULT, NULL);
 }
 
+/*
+ * Destruct a zfetch structure.
+ */
+void
+dmu_zfetch_dest(zfetch_t *zf)
+{
+	list_destroy(&zf->zf_stream);
+	rw_destroy(&zf->zf_rwlock);
+}
+
 /*
  * This function computes the actual size, in blocks, that can be prefetched,
  * and fetches it.
@@ -441,32 +474,6 @@ out:
 	return (rc);
 }
 
-/*
- * Clean-up state associated with a zfetch structure.  This frees allocated
- * structure members, empties the zf_stream tree, and generally makes things
- * nice.  This doesn't free the zfetch_t itself, that's left to the caller.
- */
-void
-dmu_zfetch_rele(zfetch_t *zf)
-{
-	zstream_t	*zs;
-	zstream_t	*zs_next;
-
-	ASSERT(!RW_LOCK_HELD(&zf->zf_rwlock));
-
-	for (zs = list_head(&zf->zf_stream); zs; zs = zs_next) {
-		zs_next = list_next(&zf->zf_stream, zs);
-
-		list_remove(&zf->zf_stream, zs);
-		mutex_destroy(&zs->zst_lock);
-		kmem_free(zs, sizeof (zstream_t));
-	}
-	list_destroy(&zf->zf_stream);
-	rw_destroy(&zf->zf_rwlock);
-
-	zf->zf_dnode = NULL;
-}
-
 /*
  * Given a zfetch and zstream structure, insert the zstream structure into the
  * AVL tree contained within the zfetch structure.  Peform the appropriate
diff --git a/module/zfs/dnode.c b/module/zfs/dnode.c
index 1a5b456aa4..1ed4aace95 100644
--- a/module/zfs/dnode.c
+++ b/module/zfs/dnode.c
@@ -74,6 +74,7 @@ dnode_cons(void *arg, void *unused, int kmflag)
 
 	list_create(&dn->dn_dbufs, sizeof (dmu_buf_impl_t),
 	    offsetof(dmu_buf_impl_t, db_link));
+	dmu_zfetch_cons(&dn->dn_zfetch);
 
 	return (0);
 }
@@ -98,6 +99,7 @@ dnode_dest(void *arg, void *unused)
 	}
 
 	list_destroy(&dn->dn_dbufs);
+	dmu_zfetch_dest(&dn->dn_zfetch);
 }
 
 void
@@ -166,6 +168,27 @@ dnode_verify(dnode_t *dn)
 	if (drop_struct_lock)
 		rw_exit(&dn->dn_struct_rwlock);
 }
+
+void
+dnode_verify_clean(dnode_t *dn)
+{
+	int i;
+
+	ASSERT(!RW_LOCK_HELD(&dn->dn_struct_rwlock));
+	ASSERT(!MUTEX_HELD(&dn->dn_mtx));
+	ASSERT(!MUTEX_HELD(&dn->dn_dbufs_mtx));
+	ASSERT(refcount_is_zero(&dn->dn_holds));
+	ASSERT(refcount_is_zero(&dn->dn_tx_holds));
+
+	for (i = 0; i < TXG_SIZE; i++) {
+		ASSERT(NULL == list_head(&dn->dn_dirty_records[i]));
+                ASSERT(0 == avl_numnodes(&dn->dn_ranges[i]));
+	}
+
+	ASSERT(NULL == list_head(&dn->dn_dbufs));
+	ASSERT(NULL == list_head(&dn->dn_zfetch.zf_stream));
+	ASSERT(!RW_LOCK_HELD(&dn->dn_zfetch.zf_rwlock));
+}
 #endif
 
 void
@@ -277,14 +300,32 @@ dnode_create(objset_impl_t *os, dnode_phys_t *dnp, dmu_buf_impl_t *db,
     uint64_t object)
 {
 	dnode_t *dn = kmem_cache_alloc(dnode_cache, KM_SLEEP);
+	int i;
 
+	DNODE_VERIFY_CLEAN(dn);
 	dn->dn_objset = os;
 	dn->dn_object = object;
 	dn->dn_dbuf = db;
 	dn->dn_phys = dnp;
 
-	if (dnp->dn_datablkszsec)
+	list_link_init(&dn->dn_link);
+	for (i = 0; i < TXG_SIZE; i++) {
+		list_link_init(&dn->dn_dirty_link[i]);
+		dn->dn_next_nblkptr[i] = 0;
+		dn->dn_next_nlevels[i] = 0;
+		dn->dn_next_indblkshift[i] = 0;
+		dn->dn_next_bonuslen[i] = 0;
+		dn->dn_next_blksz[i] = 0;
+	}
+
+	if (dnp->dn_datablkszsec) {
 		dnode_setdblksz(dn, dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT);
+	} else {
+		dn->dn_datablksz = 0;
+		dn->dn_datablkszsec = 0;
+		dn->dn_datablkshift = 0;
+	}
+
 	dn->dn_indblkshift = dnp->dn_indblkshift;
 	dn->dn_nlevels = dnp->dn_nlevels;
 	dn->dn_type = dnp->dn_type;
@@ -294,7 +335,13 @@ dnode_create(objset_impl_t *os, dnode_phys_t *dnp, dmu_buf_impl_t *db,
 	dn->dn_bonustype = dnp->dn_bonustype;
 	dn->dn_bonuslen = dnp->dn_bonuslen;
 	dn->dn_maxblkid = dnp->dn_maxblkid;
-
+	dn->dn_allocated_txg = 0;
+	dn->dn_free_txg = 0;
+	dn->dn_assigned_txg = 0;
+	dn->dn_dirtyctx = DN_UNDIRTIED;
+	dn->dn_dirtyctx_firstset = NULL;
+	dn->dn_bonus = NULL;
+	dn->dn_zio = NULL;
 	dmu_zfetch_init(&dn->dn_zfetch, dn);
 
 	ASSERT(dn->dn_phys->dn_type < DMU_OT_NUMTYPES);
@@ -336,6 +383,7 @@ dnode_destroy(dnode_t *dn)
 		dbuf_evict(dn->dn_bonus);
 		dn->dn_bonus = NULL;
 	}
+	DNODE_VERIFY_CLEAN(dn);
 	kmem_cache_free(dnode_cache, dn);
 	arc_space_return(sizeof (dnode_t), ARC_SPACE_OTHER);
 }
diff --git a/module/zfs/include/sys/dmu_zfetch.h b/module/zfs/include/sys/dmu_zfetch.h
index f65209c280..372758ccb7 100644
--- a/module/zfs/include/sys/dmu_zfetch.h
+++ b/module/zfs/include/sys/dmu_zfetch.h
@@ -65,6 +65,9 @@ typedef struct zfetch {
 
 void		dmu_zfetch_init(zfetch_t *, struct dnode *);
 void		dmu_zfetch_rele(zfetch_t *);
+void		dmu_zfetch_cons(zfetch_t *);
+void		dmu_zfetch_dest(zfetch_t *);
+
 void		dmu_zfetch(zfetch_t *, uint64_t, uint64_t, int);
 
 
diff --git a/module/zfs/include/sys/dnode.h b/module/zfs/include/sys/dnode.h
index be9e569083..f802a480f8 100644
--- a/module/zfs/include/sys/dnode.h
+++ b/module/zfs/include/sys/dnode.h
@@ -222,6 +222,7 @@ void dnode_free(dnode_t *dn, dmu_tx_t *tx);
 void dnode_byteswap(dnode_phys_t *dnp);
 void dnode_buf_byteswap(void *buf, size_t size);
 void dnode_verify(dnode_t *dn);
+void dnode_verify_clean(dnode_t *dn);
 int dnode_set_blksz(dnode_t *dn, uint64_t size, int ibs, dmu_tx_t *tx);
 uint64_t dnode_current_max_length(dnode_t *dn);
 void dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx);
@@ -259,12 +260,14 @@ void dnode_evict_dbufs(dnode_t *dn);
 _NOTE(CONSTCOND) } while (0)
 
 #define	DNODE_VERIFY(dn)		dnode_verify(dn)
+#define	DNODE_VERIFY_CLEAN(dn)		dnode_verify_clean(dn)
 #define	FREE_VERIFY(db, start, end, tx)	free_verify(db, start, end, tx)
 
 #else
 
 #define	dprintf_dnode(db, fmt, ...)
 #define	DNODE_VERIFY(dn)
+#define	DNODE_VERIFY_CLEAN(dn)
 #define	FREE_VERIFY(db, start, end, tx)
 
 #endif