diff options
author | Brian Behlendorf <[email protected]> | 2010-08-26 10:52:23 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2010-08-31 08:38:47 -0700 |
commit | a8ac8e715e50e56b5e907007ef70f39301a4d984 (patch) | |
tree | 74e498567d99840f6f67cc3bac8cbf0978715e5b /module/zfs/dmu_objset.c | |
parent | fc5bb51f08a6c91ff9ad3559d0266eeeab0b1f61 (diff) |
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 <[email protected]>
Diffstat (limited to 'module/zfs/dmu_objset.c')
-rw-r--r-- | module/zfs/dmu_objset.c | 50 |
1 files changed, 27 insertions, 23 deletions
diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c index 2d06897db..1dcfb02c5 100644 --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@ -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) { dsl_sync_task_t *dst; - struct snaparg sn; + struct snaparg *sn; spa_t *spa; minor_t minor; 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); + } if (temporary) { 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.snapname = snapname; - sn.htag = tag; - sn.props = props; - sn.recursive = recursive; - sn.needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP); - sn.temporary = temporary; - sn.ha = NULL; - sn.newds = NULL; + sn->dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); + sn->snapname = snapname; + sn->htag = tag; + sn->props = props; + sn->recursive = recursive; + sn->needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP); + sn->temporary = temporary; + sn->ha = NULL; + sn->newds = NULL; if (recursive) { err = dmu_objset_find(fsname, - dmu_objset_snapshot_one, &sn, DS_FIND_CHILDREN); + dmu_objset_snapshot_one, sn, DS_FIND_CHILDREN); } else { - err = dmu_objset_snapshot_one(fsname, &sn); + 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_dsl_dataset; if (dst->dst_err) { - dsl_dataset_name(ds, sn.failed); + dsl_dataset_name(ds, sn->failed); } 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)); - dmu_objset_rele(os, &sn); + dmu_objset_rele(os, sn); } if (err) - (void) strcpy(fsname, sn.failed); + (void) strcpy(fsname, sn->failed); if (temporary) zfs_onexit_fd_rele(cleanup_fd); - dsl_sync_task_group_destroy(sn.dstg); + dsl_sync_task_group_destroy(sn->dstg); spa_close(spa, FTAG); + kmem_free(sn, sizeof (struct snaparg)); return (err); } |