summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
Diffstat (limited to 'module')
-rw-r--r--module/zfs/dsl_dataset.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/module/zfs/dsl_dataset.c b/module/zfs/dsl_dataset.c
index 4edf34244..96a8b667f 100644
--- a/module/zfs/dsl_dataset.c
+++ b/module/zfs/dsl_dataset.c
@@ -1055,7 +1055,7 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer)
dsl_dir_t *dd;
uint64_t obj;
struct dsl_ds_destroyarg dsda = { 0 };
- dsl_dataset_t dummy_ds = { 0 };
+ dsl_dataset_t *dummy_ds;
dsda.ds = ds;
@@ -1075,8 +1075,9 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer)
}
dd = ds->ds_dir;
- dummy_ds.ds_dir = dd;
- dummy_ds.ds_object = ds->ds_object;
+ dummy_ds = kmem_zalloc(sizeof (dsl_dataset_t), KM_SLEEP);
+ dummy_ds->ds_dir = dd;
+ dummy_ds->ds_object = ds->ds_object;
/*
* Check for errors and mark this ds as inconsistent, in
@@ -1085,11 +1086,11 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer)
err = dsl_sync_task_do(dd->dd_pool, dsl_dataset_destroy_begin_check,
dsl_dataset_destroy_begin_sync, ds, NULL, 0);
if (err)
- goto out;
+ goto out_free;
err = dmu_objset_from_ds(ds, &os);
if (err)
- goto out;
+ goto out_free;
/*
* remove the objects in open context, so that we won't
@@ -1104,7 +1105,7 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer)
(void) dmu_free_object(os, obj);
}
if (err != ESRCH)
- goto out;
+ goto out_free;
/*
* Only the ZIL knows how to free log blocks.
@@ -1134,7 +1135,7 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer)
rw_exit(&dd->dd_pool->dp_config_rwlock);
if (err)
- goto out;
+ goto out_free;
/*
* Blow away the dsl_dir + head dataset.
@@ -1150,7 +1151,7 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer)
err = dsl_dataset_origin_rm_prep(&dsda, tag);
if (err) {
dsl_dir_close(dd, FTAG);
- goto out;
+ goto out_free;
}
}
@@ -1158,7 +1159,7 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer)
dsl_sync_task_create(dstg, dsl_dataset_destroy_check,
dsl_dataset_destroy_sync, &dsda, tag, 0);
dsl_sync_task_create(dstg, dsl_dir_destroy_check,
- dsl_dir_destroy_sync, &dummy_ds, FTAG, 0);
+ dsl_dir_destroy_sync, dummy_ds, FTAG, 0);
err = dsl_sync_task_group_wait(dstg);
dsl_sync_task_group_destroy(dstg);
@@ -1181,6 +1182,9 @@ dsl_dataset_destroy(dsl_dataset_t *ds, void *tag, boolean_t defer)
/* if it is successful, dsl_dir_destroy_sync will close the dd */
if (err)
dsl_dir_close(dd, FTAG);
+
+out_free:
+ kmem_free(dummy_ds, sizeof (dsl_dataset_t));
out:
dsl_dataset_disown(ds, tag);
return (err);