From 72d2035ed34eed2f4ceddb4a93283e2edb97e870 Mon Sep 17 00:00:00 2001
From: Brian Behlendorf <behlendorf1@llnl.gov>
Date: Wed, 29 Jul 2009 21:17:47 -0700
Subject: [PATCH 1/2] Updated gcc in fc11 flagged a new uninitialized variable.

---
 lib/libzfs/libzfs_dataset.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c
index 4b7ece6a34..e136d8e241 100644
--- a/lib/libzfs/libzfs_dataset.c
+++ b/lib/libzfs/libzfs_dataset.c
@@ -2580,7 +2580,7 @@ zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
 	int prefix;
 	uint64_t zoned;
 	char *path_copy;
-	int rc;
+	int rc = 0;
 
 	if (check_parents(hdl, path, &zoned, B_TRUE, &prefix) != 0)
 		return (-1);

From ee435f260c61d19765254b723740aaac7ff36da2 Mon Sep 17 00:00:00 2001
From: Brian Behlendorf <behlendorf1@llnl.gov>
Date: Wed, 29 Jul 2009 21:18:48 -0700
Subject: [PATCH 2/2] Excessively large stack frames detected. The 2.6.30
 kernel build systems sets -Wframe-larger-than=2048 which causes a warning to
 be generated when an individual stack frame exceeds 2048. This caught the
 spa_history_log() and dmu_objset_snapshot() functions which declared a data
 structure on the stack which contained a char array of MAXPATHLEN.  This in
 defined to be 4096 in the linux kernel and I imagine it is quite large under
 Solaris as well.  Regardless, the offending data structures were moved to the
 heap to correctly keep the stack depth to a minimum.  We might consider
 setting this value even lower to catch additional offenders because we are
 expecting deep stacks.

---
 module/zfs/dmu_objset.c  | 36 ++++++++++++++++++++----------------
 module/zfs/spa_history.c | 16 ++++++++++------
 2 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c
index e962c4b88f..78d3d8b6d3 100644
--- a/module/zfs/dmu_objset.c
+++ b/module/zfs/dmu_objset.c
@@ -816,46 +816,50 @@ dmu_objset_snapshot(char *fsname, char *snapname,
     nvlist_t *props, boolean_t recursive)
 {
 	dsl_sync_task_t *dst;
-	struct snaparg sn;
+	struct snaparg *sn;
 	spa_t *spa;
 	int err;
 
-	(void) strcpy(sn.failed, fsname);
+	sn = kmem_alloc(sizeof (struct snaparg), KM_SLEEP);
+	(void) strcpy(sn->failed, fsname);
 
 	err = spa_open(fsname, &spa, FTAG);
-	if (err)
+	if (err) {
+		kmem_free(sn, sizeof (struct snaparg));
 		return (err);
+	}
 
-	sn.dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
-	sn.snapname = snapname;
-	sn.props = props;
+	sn->dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
+	sn->snapname = snapname;
+	sn->props = props;
 
 	if (recursive) {
-		sn.checkperms = B_TRUE;
+		sn->checkperms = B_TRUE;
 		err = dmu_objset_find(fsname,
-		    dmu_objset_snapshot_one, &sn, DS_FIND_CHILDREN);
+		    dmu_objset_snapshot_one, sn, DS_FIND_CHILDREN);
 	} else {
-		sn.checkperms = B_FALSE;
-		err = dmu_objset_snapshot_one(fsname, &sn);
+		sn->checkperms = B_FALSE;
+		err = dmu_objset_snapshot_one(fsname, sn);
 	}
 
 	if (err == 0)
-		err = dsl_sync_task_group_wait(sn.dstg);
+		err = dsl_sync_task_group_wait(sn->dstg);
 
-	for (dst = list_head(&sn.dstg->dstg_tasks); dst;
-	    dst = list_next(&sn.dstg->dstg_tasks, dst)) {
+	for (dst = list_head(&sn->dstg->dstg_tasks); dst;
+	    dst = list_next(&sn->dstg->dstg_tasks, dst)) {
 		objset_t *os = dst->dst_arg1;
 		dsl_dataset_t *ds = os->os->os_dsl_dataset;
 		if (dst->dst_err)
-			dsl_dataset_name(ds, sn.failed);
+			dsl_dataset_name(ds, sn->failed);
 		zil_resume(dmu_objset_zil(os));
 		dmu_objset_close(os);
 	}
 
 	if (err)
-		(void) strcpy(fsname, sn.failed);
-	dsl_sync_task_group_destroy(sn.dstg);
+		(void) strcpy(fsname, sn->failed);
+	dsl_sync_task_group_destroy(sn->dstg);
 	spa_close(spa, FTAG);
+	kmem_free(sn, sizeof (struct snaparg));
 	return (err);
 }
 
diff --git a/module/zfs/spa_history.c b/module/zfs/spa_history.c
index 97d97d8478..fa57e94284 100644
--- a/module/zfs/spa_history.c
+++ b/module/zfs/spa_history.c
@@ -290,15 +290,19 @@ spa_history_log_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
 int
 spa_history_log(spa_t *spa, const char *history_str, history_log_type_t what)
 {
-	history_arg_t ha;
+	history_arg_t *ha;
+	int err;
 
 	ASSERT(what != LOG_INTERNAL);
 
-	ha.ha_history_str = history_str;
-	ha.ha_log_type = what;
-	(void) strlcpy(ha.ha_zone, spa_history_zone(), sizeof (ha.ha_zone));
-	return (dsl_sync_task_do(spa_get_dsl(spa), NULL, spa_history_log_sync,
-	    spa, &ha, 0));
+	ha = kmem_alloc(sizeof (history_arg_t), KM_SLEEP);
+	ha->ha_history_str = history_str;
+	ha->ha_log_type = what;
+	(void) strlcpy(ha->ha_zone, spa_history_zone(), sizeof (ha->ha_zone));
+	err = dsl_sync_task_do(spa_get_dsl(spa), NULL, spa_history_log_sync,
+	    spa, ha, 0);
+	kmem_free(ha, sizeof (history_arg_t));
+	return (err);
 }
 
 /*