changeset 14008:0a1a841641da

3645 dmu_send_impl: possibilty of pool hold leak 3692 Panic on zfs receive of a recursive deduplicated stream Reviewed by: Adam Leventhal <ahl@delphix.com> Reviewed by: Christopher Siden <christopher.siden@delphix.com> Reviewed by: Dan McDonald <danmcd@nexenta.com> Approved by: Richard Lowe <richlowe@richlowe.net>
author Matthew Ahrens <mahrens@delphix.com>
date Wed, 10 Apr 2013 13:54:56 -0800
parents f59d28091999
children e08c4b83071d
files usr/src/uts/common/fs/zfs/dmu_send.c
diffstat 1 files changed, 8 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/dmu_send.c	Fri Jan 11 08:53:08 2013 -0800
+++ b/usr/src/uts/common/fs/zfs/dmu_send.c	Wed Apr 10 13:54:56 2013 -0800
@@ -479,14 +479,14 @@
 	list_insert_head(&ds->ds_sendstreams, dsp);
 	mutex_exit(&ds->ds_sendstream_lock);
 
+	dsl_dataset_long_hold(ds, FTAG);
+	dsl_pool_rele(dp, tag);
+
 	if (dump_bytes(dsp, drr, sizeof (dmu_replay_record_t)) != 0) {
 		err = dsp->dsa_err;
 		goto out;
 	}
 
-	dsl_dataset_long_hold(ds, FTAG);
-	dsl_pool_rele(dp, tag);
-
 	err = traverse_dataset(ds, fromtxg, TRAVERSE_PRE | TRAVERSE_PREFETCH,
 	    backup_cb, dsp);
 
@@ -960,6 +960,7 @@
 
 	while ((gmep = avl_destroy_nodes(ca, &cookie)) != NULL) {
 		dsl_dataset_long_rele(gmep->gme_ds, gmep);
+		dsl_dataset_rele(gmep->gme_ds, gmep);
 		kmem_free(gmep, sizeof (guid_map_entry_t));
 	}
 	avl_destroy(ca);
@@ -1636,14 +1637,15 @@
 	err = dsl_pool_hold(name, FTAG, &dp);
 	if (err != 0)
 		return (err);
-	err = dsl_dataset_hold_obj(dp, snapobj, FTAG, &snapds);
+	gmep = kmem_alloc(sizeof (*gmep), KM_SLEEP);
+	err = dsl_dataset_hold_obj(dp, snapobj, gmep, &snapds);
 	if (err == 0) {
-		gmep = kmem_alloc(sizeof (guid_map_entry_t), KM_SLEEP);
 		gmep->guid = snapds->ds_phys->ds_guid;
 		gmep->gme_ds = snapds;
 		avl_add(guid_map, gmep);
 		dsl_dataset_long_hold(snapds, gmep);
-		dsl_dataset_rele(snapds, FTAG);
+	} else {
+		kmem_free(gmep, sizeof (*gmep));
 	}
 
 	dsl_pool_rele(dp, FTAG);