Fix stack dmu_objset_snapshot()

Reduce stack usage by 276 bytes by moving the snaparg struct from the
stack to the heap.  We have limited stack space we must not waste.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
Brian Behlendorf 2010-08-26 10:52:23 -07:00
parent fc5bb51f08
commit a8ac8e715e

View File

@ -946,16 +946,19 @@ dmu_objset_snapshot(char *fsname, char *snapname, char *tag,
nvlist_t *props, boolean_t recursive, boolean_t temporary, int cleanup_fd) nvlist_t *props, boolean_t recursive, boolean_t temporary, int cleanup_fd)
{ {
dsl_sync_task_t *dst; dsl_sync_task_t *dst;
struct snaparg sn; struct snaparg *sn;
spa_t *spa; spa_t *spa;
minor_t minor; minor_t minor;
int err; 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); err = spa_open(fsname, &spa, FTAG);
if (err) if (err) {
kmem_free(sn, sizeof (struct snaparg));
return (err); return (err);
}
if (temporary) { if (temporary) {
if (cleanup_fd < 0) { if (cleanup_fd < 0) {
@ -968,46 +971,47 @@ dmu_objset_snapshot(char *fsname, char *snapname, char *tag,
} }
} }
sn.dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); sn->dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
sn.snapname = snapname; sn->snapname = snapname;
sn.htag = tag; sn->htag = tag;
sn.props = props; sn->props = props;
sn.recursive = recursive; sn->recursive = recursive;
sn.needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP); sn->needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP);
sn.temporary = temporary; sn->temporary = temporary;
sn.ha = NULL; sn->ha = NULL;
sn.newds = NULL; sn->newds = NULL;
if (recursive) { if (recursive) {
err = dmu_objset_find(fsname, err = dmu_objset_find(fsname,
dmu_objset_snapshot_one, &sn, DS_FIND_CHILDREN); dmu_objset_snapshot_one, sn, DS_FIND_CHILDREN);
} else { } else {
err = dmu_objset_snapshot_one(fsname, &sn); err = dmu_objset_snapshot_one(fsname, sn);
} }
if (err == 0) 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; for (dst = list_head(&sn->dstg->dstg_tasks); dst;
dst = list_next(&sn.dstg->dstg_tasks, dst)) { dst = list_next(&sn->dstg->dstg_tasks, dst)) {
objset_t *os = dst->dst_arg1; objset_t *os = dst->dst_arg1;
dsl_dataset_t *ds = os->os_dsl_dataset; dsl_dataset_t *ds = os->os_dsl_dataset;
if (dst->dst_err) { if (dst->dst_err) {
dsl_dataset_name(ds, sn.failed); dsl_dataset_name(ds, sn->failed);
} else if (temporary) { } else if (temporary) {
dsl_register_onexit_hold_cleanup(sn.newds, tag, minor); dsl_register_onexit_hold_cleanup(sn->newds, tag, minor);
} }
if (sn.needsuspend) if (sn->needsuspend)
zil_resume(dmu_objset_zil(os)); zil_resume(dmu_objset_zil(os));
dmu_objset_rele(os, &sn); dmu_objset_rele(os, sn);
} }
if (err) if (err)
(void) strcpy(fsname, sn.failed); (void) strcpy(fsname, sn->failed);
if (temporary) if (temporary)
zfs_onexit_fd_rele(cleanup_fd); zfs_onexit_fd_rele(cleanup_fd);
dsl_sync_task_group_destroy(sn.dstg); dsl_sync_task_group_destroy(sn->dstg);
spa_close(spa, FTAG); spa_close(spa, FTAG);
kmem_free(sn, sizeof (struct snaparg));
return (err); return (err);
} }